int open_map(MAPS* rast) { int row, col; int fd; char* mapset; struct Cell_head cellhd; int bufsize; void* tmp_buf; mapset = (char*)G_find_raster2(rast->elevname, ""); if (mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), rast->elevname); rast->fd = Rast_open_old(rast->elevname, mapset); Rast_get_cellhd(rast->elevname, mapset, &cellhd); rast->raster_type = Rast_map_type(rast->elevname, mapset); if (window.ew_res < cellhd.ew_res || window.ns_res < cellhd.ns_res) G_warning(_("Region resolution shoudn't be lesser than map %s resolution. Run g.region rast=%s to set proper resolution"), rast->elevname, rast->elevname); tmp_buf=Rast_allocate_buf(rast->raster_type); rast->elev = (FCELL**) G_malloc((row_buffer_size+1) * sizeof(FCELL*)); for (row = 0; row < row_buffer_size+1; ++row) { rast->elev[row] = Rast_allocate_buf(FCELL_TYPE); Rast_get_row(rast->fd, tmp_buf,row, rast->raster_type); for (col=0;col<ncols;++col) get_cell(col, rast->elev[row], tmp_buf, rast->raster_type); } /* end elev */ G_free(tmp_buf); return 0; }
/* check compatibility of map header and region header */ void check_header(char* cellname) { const char *mapset; mapset = G_find_raster(cellname, ""); if (mapset == NULL) { G_fatal_error(_("Raster map <%s> not found"), cellname); } /* read cell header */ struct Cell_head cell_hd; Rast_get_cellhd (cellname, mapset, &cell_hd); /* check compatibility with module region */ if (!((region->ew_res == cell_hd.ew_res) && (region->ns_res == cell_hd.ns_res))) { G_fatal_error(_("cell file %s resolution differs from current region"), cellname); } else { if (opt->verbose) { G_message(_("cell %s header compatible with region header"), cellname); fflush(stderr); } } /* check type of input elevation raster and check if precision is lost */ RASTER_MAP_TYPE data_type; data_type = Rast_map_type(opt->elev_grid, mapset); #ifdef ELEV_SHORT G_verbose_message(_("Elevation stored as SHORT (%dB)"), sizeof(elevation_type)); if (data_type == FCELL_TYPE) { G_warning(_("raster %s is of type FCELL_TYPE " "--precision may be lost."), opt->elev_grid); } if (data_type == DCELL_TYPE) { G_warning(_("raster %s is of type DCELL_TYPE " "--precision may be lost."), opt->elev_grid); } #endif #ifdef ELEV_FLOAT G_verbose_message( _("Elevation stored as FLOAT (%dB)"), sizeof(elevation_type)); if (data_type == CELL_TYPE) { G_warning(_("raster %s is of type CELL_TYPE " "--you should use r.terraflow.short"), opt->elev_grid); } if (data_type == DCELL_TYPE) { G_warning(_("raster %s is of type DCELL_TYPE " "--precision may be lost."), opt->elev_grid); } #endif }
/*! * \brief Read floating-point range * * Read the floating point range file <i>drange</i>. This file is * written in binary using XDR format. * * An empty range file indicates that the min, max are undefined. This * is a valid case, and the result should be an initialized range * struct with no defined min/max. If the range file is missing and * the map is a floating-point map, this function will create a * default range by calling G_construct_default_range(). * * \param name map name * \param mapset mapset name * \param drange pointer to FPRange structure which holds fp range * * \return 1 on success * \return 2 range is empty * \return -1 on error */ int Rast_read_fp_range(const char *name, const char *mapset, struct FPRange *drange) { struct Range range; int fd; char xdr_buf[2][XDR_DOUBLE_NBYTES]; DCELL dcell1, dcell2; Rast_init(); Rast_init_fp_range(drange); if (Rast_map_type(name, mapset) == CELL_TYPE) { /* if map is integer read integer range and convert it to double */ if (Rast_read_range(name, mapset, &range) >= 0) { /* if the integer range is empty */ if (range.first_time) return 2; Rast_update_fp_range((DCELL) range.min, drange); Rast_update_fp_range((DCELL) range.max, drange); return 1; } return -1; } fd = -1; if (G_find_file2_misc("cell_misc", "f_range", name, mapset)) { fd = G_open_old_misc("cell_misc", "f_range", name, mapset); if (fd < 0) { G_warning(_("Unable to read fp range file for <%s>"), G_fully_qualified_name(name, mapset)); return -1; } if (read(fd, xdr_buf, sizeof(xdr_buf)) != sizeof(xdr_buf)) { /* if the f_range file exists, but empty file, meaning Nulls */ close(fd); G_debug(1, "Empty fp range file meaning Nulls for <%s>", G_fully_qualified_name(name, mapset)); return 2; } G_xdr_get_double(&dcell1, xdr_buf[0]); G_xdr_get_double(&dcell2, xdr_buf[1]); Rast_update_fp_range(dcell1, drange); Rast_update_fp_range(dcell2, drange); close(fd); } return 1; }
/*! * \brief Write raster range file * * This routine writes the range information for the raster map * <i>name</i> in the current mapset from the <i>range</i> structure. * A diagnostic message is printed and -1 is returned if there is an * error writing the range file. Otherwise, 0 is returned. * * This routine only writes 2 numbers (min,max) to the range * file, instead of the 4 (pmin,pmax,nmin,nmax) previously written. * If there is no defined min,max, an empty file is written. * * \param name map name * \param range pointer to Range structure which holds range info */ void Rast_write_range(const char *name, const struct Range *range) { FILE *fp; if (Rast_map_type(name, G_mapset()) != CELL_TYPE) { G_remove_misc("cell_misc", "range", name); /* remove the old file with this name */ G_fatal_error(_("Unable to write range file for <%s>"), name); } fp = G_fopen_new_misc("cell_misc", "range", name); if (!fp) { G_remove_misc("cell_misc", "range", name); /* remove the old file with this name */ G_fatal_error(_("Unable to write range file for <%s>"), name); } /* if range has been updated */ if (!range->first_time) fprintf(fp, "%ld %ld\n", (long)range->min, (long)range->max); fclose(fp); }
static void get_map_range(void) { if (Rast_map_type(mapname, "") == CELL_TYPE) { struct Range range; CELL xmin, xmax; if (Rast_read_range(mapname, "", &range) <= 0) G_fatal_error(_("Unable to read range for %s"), mapname); Rast_get_range_min_max(&range, &xmin, &xmax); max = xmax; min = xmin; } else { struct FPRange fprange; if (Rast_read_fp_range(mapname, "", &fprange) <= 0) G_fatal_error(_("Unable to read FP range for %s"), mapname); Rast_get_fp_range_min_max(&fprange, &min, &max); } }
int report_range(void) { struct FPRange drange; struct Range range; char buff[1024], buff2[300]; RASTER_MAP_TYPE inp_type; inp_type = Rast_map_type(name, ""); if (inp_type != CELL_TYPE) { if (Rast_read_fp_range(name, "", &drange) <= 0) G_fatal_error(_("Unable to read f_range for map %s"), name); Rast_get_fp_range_min_max(&drange, &old_dmin, &old_dmax); if (Rast_is_d_null_value(&old_dmin) || Rast_is_d_null_value(&old_dmax)) G_message(_("Data range is empty")); else { sprintf(buff, "%.10f", old_dmin); sprintf(buff2, "%.10f", old_dmax); G_trim_decimal(buff); G_trim_decimal(buff2); G_message(_("Data range of %s is %s to %s (entire map)"), name, buff, buff2); } } if (Rast_read_range(name, "", &range) <= 0) G_fatal_error(_("Unable to read range for map <%s>"), name); Rast_get_range_min_max(&range, &old_min, &old_max); if (Rast_is_c_null_value(&old_min) || Rast_is_c_null_value(&old_max)) G_message(_("Integer data range of %s is empty"), name); else G_message(_("Integer data range of %s is %d to %d"), name, (int)old_min, (int)old_max); return 0; }
int parse_args(int argc, char *argv[], struct globals *globals) { struct Option *group, *seeds, *bounds, *output, *method, *similarity, *threshold, *min_segment_size, #ifdef _OR_SHAPE_ *shape_weight, *smooth_weight, #endif *mem; struct Flag *diagonal, *weighted; struct Option *outband, *endt; /* required parameters */ group = G_define_standard_option(G_OPT_I_GROUP); output = G_define_standard_option(G_OPT_R_OUTPUT); threshold = G_define_option(); threshold->key = "threshold"; threshold->type = TYPE_DOUBLE; threshold->required = YES; threshold->label = _("Difference threshold between 0 and 1"); threshold->description = _("Threshold = 0 merges only identical segments; threshold = 1 merges all"); /* optional parameters */ method = G_define_option(); method->key = "method"; method->type = TYPE_STRING; method->required = NO; method->answer = "region_growing"; method->options = "region_growing,mean_shift,watershed"; method->description = _("Segmentation method"); method->guisection = _("Settings"); similarity = G_define_option(); similarity->key = "similarity"; similarity->type = TYPE_STRING; similarity->required = NO; similarity->answer = "euclidean"; similarity->options = "euclidean,manhattan"; similarity->description = _("Similarity calculation method"); similarity->guisection = _("Settings"); min_segment_size = G_define_option(); min_segment_size->key = "minsize"; min_segment_size->type = TYPE_INTEGER; min_segment_size->required = NO; min_segment_size->answer = "1"; min_segment_size->options = "1-100000"; min_segment_size->label = _("Minimum number of cells in a segment"); min_segment_size->description = _("The final step will merge small segments with their best neighbor"); min_segment_size->guisection = _("Settings"); #ifdef _OR_SHAPE_ radio_weight = G_define_option(); radio_weight->key = "radio_weight"; radio_weight->type = TYPE_DOUBLE; radio_weight->required = NO; radio_weight->answer = "1"; radio_weight->options = "0-1"; radio_weight->label = _("Importance of radiometric (input raster) values relative to shape"); radio_weight->guisection = _("Settings"); smooth_weight = G_define_option(); smooth_weight->key = "smooth_weight"; smooth_weight->type = TYPE_DOUBLE; smooth_weight->required = NO; smooth_weight->answer = "0.5"; smooth_weight->options = "0-1"; smooth_weight->label = _("Importance of smoothness relative to compactness"); smooth_weight->guisection = _("Settings"); #endif mem = G_define_option(); mem->key = "memory"; mem->type = TYPE_INTEGER; mem->required = NO; mem->answer = "300"; mem->description = _("Memory in MB"); /* TODO input for distance function */ /* debug parameters */ endt = G_define_option(); endt->key = "iterations"; endt->type = TYPE_INTEGER; endt->required = NO; endt->answer = "20"; endt->description = _("Maximum number of iterations"); endt->guisection = _("Settings"); /* Using raster for seeds * Low priority TODO: allow vector points/centroids seed input. */ seeds = G_define_standard_option(G_OPT_R_INPUT); seeds->key = "seeds"; seeds->required = NO; seeds->description = _("Name for input raster map with starting seeds"); /* Polygon constraints. */ bounds = G_define_standard_option(G_OPT_R_INPUT); bounds->key = "bounds"; bounds->required = NO; bounds->label = _("Name of input bounding/constraining raster map"); bounds->description = _("Must be integer values, each area will be segmented independent of the others"); outband = G_define_standard_option(G_OPT_R_OUTPUT); outband->key = "goodness"; outband->required = NO; outband->description = _("Name for output goodness of fit estimate map"); diagonal = G_define_flag(); diagonal->key = 'd'; diagonal->description = _("Use 8 neighbors (3x3 neighborhood) instead of the default 4 neighbors for each pixel"); diagonal->guisection = _("Settings"); weighted = G_define_flag(); weighted->key = 'w'; weighted->description = _("Weighted input, do not perform the default scaling of input raster maps"); weighted->guisection = _("Settings"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* Check and save parameters */ globals->image_group = group->answer; if (G_legal_filename(output->answer) == TRUE) globals->out_name = output->answer; else G_fatal_error("Invalid output raster name"); /* Note: this threshold is scaled after we know more at the beginning of create_isegs() */ globals->alpha = atof(threshold->answer); if (globals->alpha <= 0 || globals->alpha >= 1) G_fatal_error(_("Threshold should be > 0 and < 1")); /* segmentation methods */ if (strcmp(method->answer, "region_growing") == 0) { globals->method = ORM_RG; globals->method_fn = region_growing; } else if (strcmp(method->answer, "mean_shift") == 0) { globals->method = ORM_MS; globals->method_fn = mean_shift; } else if (strcmp(method->answer, "watershed") == 0) { globals->method = ORM_WS; globals->method_fn = watershed; } else G_fatal_error(_("Unable to assign segmentation method")); G_debug(1, "segmentation method: %s", method->answer); /* distance methods for similarity measurement */ if (strcmp(similarity->answer, "euclidean") == 0) globals->calculate_similarity = calculate_euclidean_similarity; else if (strcmp(similarity->answer, "manhattan") == 0) globals->calculate_similarity = calculate_manhattan_similarity; else G_fatal_error(_("Invalid similarity method")); #ifdef _OR_SHAPE_ /* consider shape */ globals->radio_weight = atof(radio_weight->answer); if (globals->radio_weight <= 0) G_fatal_error(_("Option '%s' must be > 0"), radio_weight->key); if (globals->radio_weight > 1) G_fatal_error(_("Option '%s' must be <= 1"), radio_weight->key); globals->smooth_weight = atof(smooth_weight->answer); if (globals->smooth_weight < 0) G_fatal_error(_("Option '%s' must be >= 0"), smooth_weight->key); if (globals->smooth_weight > 1) G_fatal_error(_("Option '%s' must be <= 1"), smooth_weight->key); #else globals->radio_weight = 1; globals->smooth_weight = 0.5; #endif globals->min_segment_size = atoi(min_segment_size->answer); if (diagonal->answer == FALSE) { globals->find_neighbors = find_four_neighbors; globals->nn = 4; G_debug(1, "four pixel neighborhood"); } else if (diagonal->answer == TRUE) { globals->find_neighbors = find_eight_neighbors; globals->nn = 8; G_debug(1, "eight (3x3) pixel neighborhood"); } /* default/0 for performing the scaling * selected/1 if scaling should be skipped. */ globals->weighted = weighted->answer; globals->seeds = seeds->answer; if (globals->seeds) { if (G_find_raster(globals->seeds, "") == NULL) { G_fatal_error(_("Seeds raster map not found")); } if (Rast_map_type(globals->seeds, "") != CELL_TYPE) { G_fatal_error(_("Seeeds raster map must be CELL type (integers)")); } } if (bounds->answer == NULL) { globals->bounds_map = NULL; } else { globals->bounds_map = bounds->answer; if ((globals->bounds_mapset = G_find_raster(globals->bounds_map, "")) == NULL) { G_fatal_error(_("Segmentation constraint/boundary raster map not found")); } if (Rast_map_type(globals->bounds_map, globals->bounds_mapset) != CELL_TYPE) { G_fatal_error(_("Segmentation constraint raster map must be CELL type (integers)")); } } /* other data */ globals->nrows = Rast_window_rows(); globals->ncols = Rast_window_cols(); /* debug help */ if (outband->answer == NULL) globals->out_band = NULL; else { if (G_legal_filename(outband->answer) == TRUE) globals->out_band = outband->answer; else G_fatal_error(_("Invalid output raster name for goodness of fit")); } if (endt->answer) { if (atoi(endt->answer) > 0) globals->end_t = atoi(endt->answer); else { globals->end_t = 100; G_warning(_("Invalid number of iterations, 100 will be used")); } } else globals->end_t = 1000; if (mem->answer && atoi(mem->answer) > 10) globals->mb = atoi(mem->answer); else { globals->mb = 300; G_warning(_("Invalid number of MB, 300 will be used")); } return TRUE; }
int main(int argc, char *argv[]) { const char *name; const char *mapset; long x, y; double dx; RASTER_MAP_TYPE map_type; int i; int from_stdin = FALSE; struct GModule *module; struct { struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str, *fmt_coeff; } parm; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("category")); module->description = _("Manages category values and labels associated " "with user-specified raster map layers."); parm.map = G_define_standard_option(G_OPT_R_MAP); parm.cats = G_define_standard_option(G_OPT_V_CATS); parm.cats->multiple = YES; parm.cats->guisection = _("Selection"); parm.vals = G_define_option(); parm.vals->key = "vals"; parm.vals->type = TYPE_DOUBLE; parm.vals->multiple = YES; parm.vals->required = NO; parm.vals->label = _("Comma separated value list"); parm.vals->description = _("Example: 1.4,3.8,13"); parm.vals->guisection = _("Selection"); parm.fs = G_define_standard_option(G_OPT_F_SEP); parm.fs->answer = "tab"; parm.raster = G_define_standard_option(G_OPT_R_INPUT); parm.raster->key = "raster"; parm.raster->required = NO; parm.raster->description = _("Raster map from which to copy category table"); parm.raster->guisection = _("Define"); parm.file = G_define_standard_option(G_OPT_F_INPUT); parm.file->key = "rules"; parm.file->required = NO; parm.file->description = _("File containing category label rules (or \"-\" to read from stdin)"); parm.file->guisection = _("Define"); parm.fmt_str = G_define_option(); parm.fmt_str->key = "format"; parm.fmt_str->type = TYPE_STRING; parm.fmt_str->required = NO; parm.fmt_str->label = _("Default label or format string for dynamic labeling"); parm.fmt_str->description = _("Used when no explicit label exists for the category"); parm.fmt_coeff = G_define_option(); parm.fmt_coeff->key = "coefficients"; parm.fmt_coeff->type = TYPE_DOUBLE; parm.fmt_coeff->required = NO; parm.fmt_coeff->key_desc = "mult1,offset1,mult2,offset2"; /* parm.fmt_coeff->answer = "0.0,0.0,0.0,0.0"; */ parm.fmt_coeff->label = _("Dynamic label coefficients"); parm.fmt_coeff->description = _("Two pairs of category multiplier and offsets, for $1 and $2"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); name = parm.map->answer; fs = G_option_to_separator(parm.fs); mapset = G_find_raster2(name, ""); if (mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), name); map_type = Rast_map_type(name, mapset); /* create category labels */ if (parm.raster->answer || parm.file->answer || parm.fmt_str->answer || parm.fmt_coeff->answer) { /* restrict editing to current mapset */ if (strcmp(mapset, G_mapset()) != 0) G_fatal_error(_("Raster map <%s> not found in current mapset"), name); /* use cats from another map */ if (parm.raster->answer) { int fd; const char *cmapset; cmapset = G_find_raster2(parm.raster->answer, ""); if (cmapset == NULL) G_fatal_error(_("Raster map <%s> not found"), parm.raster->answer); fd = Rast_open_old(name, mapset); Rast_init_cats("", &cats); if (0 > Rast_read_cats(parm.raster->answer, cmapset, &cats)) G_fatal_error(_("Unable to read category file of raster map <%s@%s>"), parm.raster->answer, cmapset); Rast_write_cats(name, &cats); G_message(_("Category table for <%s> set from <%s>"), name, parm.raster->answer); Rast_close(fd); } /* load cats from rules file */ if (parm.file->answer) { FILE *fp; char **tokens; int ntokens; char *e1; char *e2; if (strcmp("-", parm.file->answer) == 0) { from_stdin = TRUE; fp = stdin; } else { fp = fopen(parm.file->answer, "r"); if (!fp) G_fatal_error(_("Unable to open file <%s>"), parm.file->answer); } Rast_init_cats("", &cats); for (;;) { char buf[1024]; DCELL d1, d2; int parse_error = 0; if (!G_getl2(buf, sizeof(buf), fp)) break; tokens = G_tokenize(buf, fs); ntokens = G_number_of_tokens(tokens); if (ntokens == 3) { d1 = strtod(tokens[0], &e1); d2 = strtod(tokens[1], &e2); if (*e1 == 0 && *e2 == 0) Rast_set_d_cat(&d1, &d2, tokens[2], &cats); else parse_error = 1; } else if (ntokens == 2) { d1 = strtod(tokens[0], &e1); if (*e1 == 0) Rast_set_d_cat(&d1, &d1, tokens[1], &cats); else parse_error = 1; } else if (!strlen(buf)) continue; else parse_error = 1; if (parse_error) G_fatal_error(_("Incorrect format of input rules. " "Check separators. Invalid line is:\n%s"), buf); } G_free_tokens(tokens); Rast_write_cats(name, &cats); if (!from_stdin) fclose(fp); } /* set dynamic cat rules for cats without explicit labels */ if (parm.fmt_str->answer || parm.fmt_coeff->answer) { char *fmt_str; double m1, a1, m2, a2; /* read existing values */ Rast_init_cats("", &cats); if (0 > Rast_read_cats(name, G_mapset(), &cats)) G_warning(_("Unable to read category file of raster map <%s@%s>"), name, G_mapset()); if (parm.fmt_str->answer) { fmt_str = G_malloc(strlen(parm.fmt_str->answer) > strlen(cats.fmt) ? strlen(parm.fmt_str->answer) + 1 : strlen(cats.fmt) + 1); strcpy(fmt_str, parm.fmt_str->answer); } else { fmt_str = G_malloc(strlen(cats.fmt) + 1); strcpy(fmt_str, cats.fmt); } m1 = cats.m1; a1 = cats.a1; m2 = cats.m2; a2 = cats.a2; if (parm.fmt_coeff->answer) { m1 = atof(parm.fmt_coeff->answers[0]); a1 = atof(parm.fmt_coeff->answers[1]); m2 = atof(parm.fmt_coeff->answers[2]); a2 = atof(parm.fmt_coeff->answers[3]); } Rast_set_cats_fmt(fmt_str, m1, a1, m2, a2, &cats); Rast_write_cats(name, &cats); } Rast_free_cats(&cats); exit(EXIT_SUCCESS); } else { if (Rast_read_cats(name, mapset, &cats) < 0) G_fatal_error(_("Unable to read category file of raster map <%s> in <%s>"), name, mapset); } /* describe the category labels */ /* if no cats requested, use r.describe to get the cats */ if (parm.cats->answer == NULL) { if (map_type == CELL_TYPE) { get_cats(name, mapset); while (next_cat(&x)) print_label(x); exit(EXIT_SUCCESS); } } else { if (map_type != CELL_TYPE) G_warning(_("The map is floating point! Ignoring cats list, using vals list")); else { /* integer map */ for (i = 0; parm.cats->answers[i]; i++) if (!scan_cats(parm.cats->answers[i], &x, &y)) { G_usage(); exit(EXIT_FAILURE); } for (i = 0; parm.cats->answers[i]; i++) { scan_cats(parm.cats->answers[i], &x, &y); while (x <= y) print_label(x++); } exit(EXIT_SUCCESS); } } if (parm.vals->answer == NULL) G_fatal_error(_("vals argument is required for floating point map!")); for (i = 0; parm.vals->answers[i]; i++) if (!scan_vals(parm.vals->answers[i], &dx)) { G_usage(); exit(EXIT_FAILURE); } for (i = 0; parm.vals->answers[i]; i++) { scan_vals(parm.vals->answers[i], &dx); print_d_label(dx); } exit(EXIT_SUCCESS); }
void* raster2array(const char* name, struct Cell_head* header, int* rows, int* cols, RASTER_MAP_TYPE out_type) { // Open the raster map and load the dem // for simplicity sake, the dem will be an array of // doubles, converted from any possible GRASS CELL type. //ORG char* mapset = G_find_cell2(name, ""); char* mapset = G_find_raster(name, ""); if (mapset == NULL) G_fatal_error("Raster map <%s> not found", name); // Find out the cell type of the DEM //ORG RASTER_MAP_TYPE type = G_raster_map_type(name, mapset); RASTER_MAP_TYPE type = Rast_map_type(name, mapset); // Get a file descriptor for the DEM raster map int infd; //ORG if ((infd = G_open_cell_old(name, mapset)) < 0) if ((infd = Rast_open_old(name, mapset)) < 0) G_fatal_error("Unable to open raster map <%s>", name); // Get header info for the DEM raster map struct Cell_head cellhd; //ORG if (G_get_cellhd(name, mapset, &cellhd) < 0) //ORG G_fatal_error("Unable to open raster map <%s>", name); Rast_get_cellhd(name, mapset, &cellhd); // Create a GRASS buffer for the DEM raster //ORG void* inrast = G_allocate_raster_buf(type); void* inrast = Rast_allocate_buf(type); // Get the max rows and max cols from the window information, since the // header gives the values for the full raster //ORG const int maxr = G_window_rows(); //ORG const int maxc = G_window_cols(); const int maxr = Rast_window_rows(); const int maxc = Rast_window_cols(); // Read in the raster line by line, copying it into the double array // rast for return. void* rast; switch (out_type) { case CELL_TYPE: rast = (int*) calloc(maxr * maxc, sizeof(int)); break; case FCELL_TYPE: rast = (float*) calloc(maxr * maxc, sizeof(float)); break; case DCELL_TYPE: rast = (double*) calloc(maxr * maxc, sizeof(double)); break; } if (rast == NULL) { G_fatal_error("Unable to allocate memory for raster map <%s>", name); } int row, col; for (row = 0; row < maxr; ++row) { //ORG if (G_get_raster_row(infd, inrast, row, type) < 0) //ORG G_fatal_error("Unable to read raster map <%s> row %d", name, row); Rast_get_row(infd, inrast, row, type); for (col = 0; col < maxc; ++col) { int index = col + row * maxc; if (out_type == CELL_TYPE) { switch (type) { case CELL_TYPE: ((int*) rast)[index] = ((int *) inrast)[col]; break; case FCELL_TYPE: ((int*) rast)[index] = (int) ((float *) inrast)[col]; break; case DCELL_TYPE: ((int*) rast)[index] = (int) ((double *) inrast)[col]; break; default: G_fatal_error("Unknown cell type"); break; } } if (out_type == FCELL_TYPE) { switch (type) { case CELL_TYPE: ((float*) rast)[index] = (float) ((int *) inrast)[col]; break; case FCELL_TYPE: ((float*) rast)[index] = ((float *) inrast)[col]; break; case DCELL_TYPE: ((float*) rast)[index] = (float) ((double *) inrast)[col]; break; default: G_fatal_error("Unknown cell type"); break; } } if (out_type == DCELL_TYPE) { switch (type) { case CELL_TYPE: ((double*) rast)[index] = (double) ((int *) inrast)[col]; break; case FCELL_TYPE: ((double*) rast)[index] = (double) ((float *) inrast)[col]; break; case DCELL_TYPE: ((double*) rast)[index] = ((double *) inrast)[col]; break; default: G_fatal_error("Unknown cell type"); break; } } } } // Return cellhd, maxr, and maxc by pointer if (header != NULL) *header = cellhd; if (rows != NULL) *rows = maxr; if (cols != NULL) *cols = maxc; return rast; }
/*! * \brief Read raster range (CELL) * * This routine reads the range information for the raster map * <i>name</i> in <i>mapset</i> into the <i>range</i> structure. * * A diagnostic message is printed and -1 is returned if there is an error * reading the range file. Otherwise, 0 is returned. * * Old range file (those with 4 numbers) should treat zeros in this * file as NULL-values. New range files (those with just 2 numbers) * should treat these numbers as real data (zeros are real data in * this case). An empty range file indicates that the min, max are * undefined. This is a valid case, and the result should be an * initialized range struct with no defined min/max. If the range file * is missing and the map is a floating-point map, this function will * create a default range by calling G_construct_default_range(). * * \param name map name * \param mapset mapset name * \param[out] range pointer to Range structure which holds range info * * \return -1 on error * \return 1 on success * \return 2 if range is empty * \return 3 if raster map is floating-point, get range from quant rules */ int Rast_read_range(const char *name, const char *mapset, struct Range *range) { FILE *fd; CELL x[4]; char buf[200]; int n, count; struct Quant quant; struct FPRange drange; Rast_init_range(range); fd = NULL; /* if map is not integer, read quant rules, and get limits */ if (Rast_map_type(name, mapset) != CELL_TYPE) { DCELL dmin, dmax; if (Rast_read_quant(name, mapset, &quant) < 0) { G_warning(_("Unable to read quant rules for raster map <%s>"), G_fully_qualified_name(name, mapset)); return -1; } if (Rast_quant_is_truncate(&quant) || Rast_quant_is_round(&quant)) { if (Rast_read_fp_range(name, mapset, &drange) >= 0) { Rast_get_fp_range_min_max(&drange, &dmin, &dmax); if (Rast_quant_is_truncate(&quant)) { x[0] = (CELL) dmin; x[1] = (CELL) dmax; } else { /* round */ if (dmin > 0) x[0] = (CELL) (dmin + .5); else x[0] = (CELL) (dmin - .5); if (dmax > 0) x[1] = (CELL) (dmax + .5); else x[1] = (CELL) (dmax - .5); } } else return -1; } else Rast_quant_get_limits(&quant, &dmin, &dmax, &x[0], &x[1]); Rast_update_range(x[0], range); Rast_update_range(x[1], range); return 3; } if (G_find_file2_misc("cell_misc", "range", name, mapset)) { fd = G_fopen_old_misc("cell_misc", "range", name, mapset); if (!fd) { G_warning(_("Unable to read range file for <%s>"), G_fully_qualified_name(name, mapset)); return -1; } /* if range file exists but empty */ if (!fgets(buf, sizeof buf, fd)) { if (fd) fclose(fd); return 2; } x[0] = x[1] = x[2] = x[3] = 0; count = sscanf(buf, "%d%d%d%d", &x[0], &x[1], &x[2], &x[3]); /* if wrong format */ if (count <= 0) { if (fd) fclose(fd); G_warning(_("Unable to read range file for <%s>"), G_fully_qualified_name(name, mapset)); return -1; } for (n = 0; n < count; n++) { /* if count==4, the range file is old (4.1) and 0's in it have to be ignored */ if (count < 4 || x[n]) Rast_update_range((CELL) x[n], range); } fclose(fd); } return 1; }
int main(int argc, char *argv[]) { int nrows, ncols; int row, col; char *viflag; /*Switch for particular index */ char *desc; struct GModule *module; struct { struct Option *viname, *red, *nir, *green, *blue, *chan5, *chan7, *sl_slope, *sl_int, *sl_red, *bits, *output; } opt; struct History history; /*metadata */ struct Colors colors; /*Color rules */ char *result; /*output raster name */ int infd_redchan, infd_nirchan, infd_greenchan; int infd_bluechan, infd_chan5chan, infd_chan7chan; int outfd; char *bluechan, *greenchan, *redchan, *nirchan, *chan5chan, *chan7chan; DCELL *inrast_redchan, *inrast_nirchan, *inrast_greenchan; DCELL *inrast_bluechan, *inrast_chan5chan, *inrast_chan7chan; DCELL *outrast; RASTER_MAP_TYPE data_type_redchan; RASTER_MAP_TYPE data_type_nirchan, data_type_greenchan; RASTER_MAP_TYPE data_type_bluechan; RASTER_MAP_TYPE data_type_chan5chan, data_type_chan7chan; DCELL msavip1, msavip2, msavip3, dnbits; CELL val1, val2; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("vegetation index")); G_add_keyword(_("biophysical parameters")); module->label = _("Calculates different types of vegetation indices."); module->description = _("Uses red and nir bands mostly, " "and some indices require additional bands."); /* Define the different options */ opt.red = G_define_standard_option(G_OPT_R_INPUT); opt.red->key = "red"; opt.red->label = _("Name of input red channel surface reflectance map"); opt.red->description = _("Range: [0.0;1.0]"); opt.output = G_define_standard_option(G_OPT_R_OUTPUT); opt.viname = G_define_option(); opt.viname->key = "viname"; opt.viname->type = TYPE_STRING; opt.viname->required = YES; opt.viname->description = _("Type of vegetation index"); desc = NULL; G_asprintf(&desc, "arvi;%s;dvi;%s;evi;%s;evi2;%s;gvi;%s;gari;%s;gemi;%s;ipvi;%s;msavi;%s;" "msavi2;%s;ndvi;%s;pvi;%s;savi;%s;sr;%s;vari;%s;wdvi;%s", _("Atmospherically Resistant Vegetation Index"), _("Difference Vegetation Index"), _("Enhanced Vegetation Index"), _("Enhanced Vegetation Index 2"), _("Green Vegetation Index"), _("Green Atmospherically Resistant Vegetation Index"), _("Global Environmental Monitoring Index"), _("Infrared Percentage Vegetation Index"), _("Modified Soil Adjusted Vegetation Index"), _("second Modified Soil Adjusted Vegetation Index"), _("Normalized Difference Vegetation Index"), _("Perpendicular Vegetation Index"), _("Soil Adjusted Vegetation Index"), _("Simple Ratio"), _("Visible Atmospherically Resistant Index"), _("Weighted Difference Vegetation Index")); opt.viname->descriptions = desc; opt.viname->options = "arvi,dvi,evi,evi2,gvi,gari,gemi,ipvi,msavi,msavi2,ndvi,pvi,savi,sr,vari,wdvi"; opt.viname->answer = "ndvi"; opt.viname->key_desc = _("type"); opt.nir = G_define_standard_option(G_OPT_R_INPUT); opt.nir->key = "nir"; opt.nir->required = NO; opt.nir->label = _("Name of input nir channel surface reflectance map"); opt.nir->description = _("Range: [0.0;1.0]"); opt.nir->guisection = _("Optional inputs"); opt.green = G_define_standard_option(G_OPT_R_INPUT); opt.green->key = "green"; opt.green->required = NO; opt.green->label = _("Name of input green channel surface reflectance map"); opt.green->description = _("Range: [0.0;1.0]"); opt.green->guisection = _("Optional inputs"); opt.blue = G_define_standard_option(G_OPT_R_INPUT); opt.blue->key = "blue"; opt.blue->required = NO; opt.blue->label = _("Name of input blue channel surface reflectance map"); opt.blue->description = _("Range: [0.0;1.0]"); opt.blue->guisection = _("Optional inputs"); opt.chan5 = G_define_standard_option(G_OPT_R_INPUT); opt.chan5->key = "band5"; opt.chan5->required = NO; opt.chan5->label = _("Name of input 5th channel surface reflectance map"); opt.chan5->description = _("Range: [0.0;1.0]"); opt.chan5->guisection = _("Optional inputs"); opt.chan7 = G_define_standard_option(G_OPT_R_INPUT); opt.chan7->key = "band7"; opt.chan7->required = NO; opt.chan7->label = _("Name of input 7th channel surface reflectance map"); opt.chan7->description = _("Range: [0.0;1.0]"); opt.chan7->guisection = _("Optional inputs"); opt.sl_slope = G_define_option(); opt.sl_slope->key = "soil_line_slope"; opt.sl_slope->type = TYPE_DOUBLE; opt.sl_slope->required = NO; opt.sl_slope->description = _("Value of the slope of the soil line (MSAVI only)"); opt.sl_slope->guisection = _("MSAVI settings"); opt.sl_int = G_define_option(); opt.sl_int->key = "soil_line_intercept"; opt.sl_int->type = TYPE_DOUBLE; opt.sl_int->required = NO; opt.sl_int->description = _("Value of the intercept of the soil line (MSAVI only)"); opt.sl_int->guisection = _("MSAVI settings"); opt.sl_red = G_define_option(); opt.sl_red->key = "soil_noise_reduction"; opt.sl_red->type = TYPE_DOUBLE; opt.sl_red->required = NO; opt.sl_red->description = _("Value of the factor of reduction of soil noise (MSAVI only)"); opt.sl_red->guisection = _("MSAVI settings"); opt.bits = G_define_option(); opt.bits->key = "storage_bit"; opt.bits->type = TYPE_INTEGER; opt.bits->required = NO; opt.bits->label = _("Maximum bits for digital numbers"); opt.bits->description = _("If data is in Digital Numbers (i.e. integer type), give the max bits (i.e. 8 for Landsat -> [0-255])"); opt.bits->options = "7,8,10,16"; opt.bits->answer = "8"; if (G_parser(argc, argv)) exit(EXIT_FAILURE); viflag = opt.viname->answer; redchan = opt.red->answer; nirchan = opt.nir->answer; greenchan = opt.green->answer; bluechan = opt.blue->answer; chan5chan = opt.chan5->answer; chan7chan = opt.chan7->answer; if(opt.sl_slope->answer) msavip1 = atof(opt.sl_slope->answer); if(opt.sl_int->answer) msavip2 = atof(opt.sl_int->answer); if(opt.sl_red->answer) msavip3 = atof(opt.sl_red->answer); if(opt.bits->answer) dnbits = atof(opt.bits->answer); result = opt.output->answer; G_verbose_message(_("Calculating %s..."), viflag); if (!strcasecmp(viflag, "sr") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("sr index requires red and nir maps")); if (!strcasecmp(viflag, "ndvi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("ndvi index requires red and nir maps")); if (!strcasecmp(viflag, "ipvi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("ipvi index requires red and nir maps")); if (!strcasecmp(viflag, "dvi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("dvi index requires red and nir maps")); if (!strcasecmp(viflag, "pvi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("pvi index requires red and nir maps")); if (!strcasecmp(viflag, "wdvi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("wdvi index requires red and nir maps")); if (!strcasecmp(viflag, "savi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("savi index requires red and nir maps")); if (!strcasecmp(viflag, "msavi") && (!(opt.red->answer) || !(opt.nir->answer) || !(opt.sl_slope->answer) || !(opt.sl_int->answer) || !(opt.sl_red->answer)) ) G_fatal_error(_("msavi index requires red and nir maps, and 3 parameters related to soil line")); if (!strcasecmp(viflag, "msavi2") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("msavi2 index requires red and nir maps")); if (!strcasecmp(viflag, "gemi") && (!(opt.red->answer) || !(opt.nir->answer)) ) G_fatal_error(_("gemi index requires red and nir maps")); if (!strcasecmp(viflag, "arvi") && (!(opt.red->answer) || !(opt.nir->answer) || !(opt.blue->answer)) ) G_fatal_error(_("arvi index requires blue, red and nir maps")); if (!strcasecmp(viflag, "evi") && (!(opt.red->answer) || !(opt.nir->answer) || !(opt.blue->answer)) ) G_fatal_error(_("evi index requires blue, red and nir maps")); if (!strcasecmp(viflag, "evi2") && (!(opt.red->answer) || !(opt.nir->answer) ) ) G_fatal_error(_("evi2 index requires red and nir maps")); if (!strcasecmp(viflag, "vari") && (!(opt.red->answer) || !(opt.green->answer) || !(opt.blue->answer)) ) G_fatal_error(_("vari index requires blue, green and red maps")); if (!strcasecmp(viflag, "gari") && (!(opt.red->answer) || !(opt.nir->answer) || !(opt.green->answer) || !(opt.blue->answer)) ) G_fatal_error(_("gari index requires blue, green, red and nir maps")); if (!strcasecmp(viflag, "gvi") && (!(opt.red->answer) || !(opt.nir->answer) || !(opt.green->answer) || !(opt.blue->answer) || !(opt.chan5->answer) || !(opt.chan7->answer)) ) G_fatal_error(_("gvi index requires blue, green, red, nir, chan5 and chan7 maps")); infd_redchan = Rast_open_old(redchan, ""); data_type_redchan = Rast_map_type(redchan, ""); inrast_redchan = Rast_allocate_buf(data_type_redchan); if (nirchan) { infd_nirchan = Rast_open_old(nirchan, ""); data_type_nirchan = Rast_map_type(nirchan, ""); inrast_nirchan = Rast_allocate_buf(data_type_nirchan); } if (greenchan) { infd_greenchan = Rast_open_old(greenchan, ""); data_type_greenchan = Rast_map_type(greenchan, ""); inrast_greenchan = Rast_allocate_buf(data_type_greenchan); } if (bluechan) { infd_bluechan = Rast_open_old(bluechan, ""); data_type_bluechan = Rast_map_type(bluechan, ""); inrast_bluechan = Rast_allocate_buf(data_type_bluechan); } if (chan5chan) { infd_chan5chan = Rast_open_old(chan5chan, ""); data_type_chan5chan = Rast_map_type(chan5chan, ""); inrast_chan5chan = Rast_allocate_buf(data_type_chan5chan); } if (chan7chan) { infd_chan7chan = Rast_open_old(chan7chan, ""); data_type_chan7chan = Rast_map_type(chan7chan, ""); inrast_chan7chan = Rast_allocate_buf(data_type_chan7chan); } nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* Create New raster files */ outfd = Rast_open_new(result, DCELL_TYPE); outrast = Rast_allocate_d_buf(); /* Process pixels */ for (row = 0; row < nrows; row++) { DCELL d_bluechan; DCELL d_greenchan; DCELL d_redchan; DCELL d_nirchan; DCELL d_chan5chan; DCELL d_chan7chan; G_percent(row, nrows, 2); /* read input maps */ Rast_get_row(infd_redchan,inrast_redchan,row,data_type_redchan); if (nirchan) { Rast_get_row(infd_nirchan,inrast_nirchan,row,data_type_nirchan); } if (bluechan) { Rast_get_row(infd_bluechan,inrast_bluechan,row,data_type_bluechan); } if (greenchan) { Rast_get_row(infd_greenchan,inrast_greenchan,row,data_type_greenchan); } if (chan5chan) { Rast_get_row(infd_chan5chan,inrast_chan5chan,row,data_type_chan5chan); } if (chan7chan) { Rast_get_row(infd_chan7chan,inrast_chan7chan,row,data_type_chan7chan); } /* process the data */ for (col = 0; col < ncols; col++) { switch(data_type_redchan){ case CELL_TYPE: d_redchan = (double) ((CELL *) inrast_redchan)[col]; if(opt.bits->answer) d_redchan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_redchan = (double) ((FCELL *) inrast_redchan)[col]; break; case DCELL_TYPE: d_redchan = ((DCELL *) inrast_redchan)[col]; break; } if (nirchan) { switch(data_type_nirchan){ case CELL_TYPE: d_nirchan = (double) ((CELL *) inrast_nirchan)[col]; if(opt.bits->answer) d_nirchan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_nirchan = (double) ((FCELL *) inrast_nirchan)[col]; break; case DCELL_TYPE: d_nirchan = ((DCELL *) inrast_nirchan)[col]; break; } } if (greenchan) { switch(data_type_greenchan){ case CELL_TYPE: d_greenchan = (double) ((CELL *) inrast_greenchan)[col]; if(opt.bits->answer) d_greenchan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_greenchan = (double) ((FCELL *) inrast_greenchan)[col]; break; case DCELL_TYPE: d_greenchan = ((DCELL *) inrast_greenchan)[col]; break; } } if (bluechan) { switch(data_type_bluechan){ case CELL_TYPE: d_bluechan = (double) ((CELL *) inrast_bluechan)[col]; if(opt.bits->answer) d_bluechan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_bluechan = (double) ((FCELL *) inrast_bluechan)[col]; break; case DCELL_TYPE: d_bluechan = ((DCELL *) inrast_bluechan)[col]; break; } } if (chan5chan) { switch(data_type_chan5chan){ case CELL_TYPE: d_chan5chan = (double) ((CELL *) inrast_chan5chan)[col]; if(opt.bits->answer) d_chan5chan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_chan5chan = (double) ((FCELL *) inrast_chan5chan)[col]; break; case DCELL_TYPE: d_chan5chan = ((DCELL *) inrast_chan5chan)[col]; break; } } if (chan7chan) { switch(data_type_chan7chan){ case CELL_TYPE: d_chan7chan = (double) ((CELL *) inrast_chan7chan)[col]; if(opt.bits->answer) d_chan7chan *= 1.0/(pow(2,dnbits)-1); break; case FCELL_TYPE: d_chan7chan = (double) ((FCELL *) inrast_chan7chan)[col]; break; case DCELL_TYPE: d_chan7chan = ((DCELL *) inrast_chan7chan)[col]; break; } } if (Rast_is_d_null_value(&d_redchan) || ((nirchan) && Rast_is_d_null_value(&d_nirchan)) || ((greenchan) && Rast_is_d_null_value(&d_greenchan)) || ((bluechan) && Rast_is_d_null_value(&d_bluechan)) || ((chan5chan) && Rast_is_d_null_value(&d_chan5chan)) || ((chan7chan) && Rast_is_d_null_value(&d_chan7chan))) { Rast_set_d_null_value(&outrast[col], 1); } else { /* calculate simple_ratio */ if (!strcasecmp(viflag, "sr")) outrast[col] = s_r(d_redchan, d_nirchan); /* calculate ndvi */ if (!strcasecmp(viflag, "ndvi")) { if (d_redchan + d_nirchan < 0.001) Rast_set_d_null_value(&outrast[col], 1); else outrast[col] = nd_vi(d_redchan, d_nirchan); } if (!strcasecmp(viflag, "ipvi")) outrast[col] = ip_vi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "dvi")) outrast[col] = d_vi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "evi")) outrast[col] = e_vi(d_bluechan, d_redchan, d_nirchan); if (!strcasecmp(viflag, "evi2")) outrast[col] = e_vi2(d_redchan, d_nirchan); if (!strcasecmp(viflag, "pvi")) outrast[col] = p_vi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "wdvi")) outrast[col] = wd_vi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "savi")) outrast[col] = sa_vi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "msavi")) outrast[col] = msa_vi(d_redchan, d_nirchan, msavip1, msavip2, msavip3); if (!strcasecmp(viflag, "msavi2")) outrast[col] = msa_vi2(d_redchan, d_nirchan); if (!strcasecmp(viflag, "gemi")) outrast[col] = ge_mi(d_redchan, d_nirchan); if (!strcasecmp(viflag, "arvi")) outrast[col] = ar_vi(d_redchan, d_nirchan, d_bluechan); if (!strcasecmp(viflag, "gvi")) outrast[col] = g_vi(d_bluechan, d_greenchan, d_redchan, d_nirchan, d_chan5chan, d_chan7chan); if (!strcasecmp(viflag, "gari")) outrast[col] = ga_ri(d_redchan, d_nirchan, d_bluechan, d_greenchan); if (!strcasecmp(viflag, "vari")) outrast[col] = va_ri(d_redchan, d_greenchan, d_bluechan); } } Rast_put_d_row(outfd, outrast); } G_percent(1, 1, 1); G_free(inrast_redchan); Rast_close(infd_redchan); if (nirchan) { G_free(inrast_nirchan); Rast_close(infd_nirchan); } if (greenchan) { G_free(inrast_greenchan); Rast_close(infd_greenchan); } if (bluechan) { G_free(inrast_bluechan); Rast_close(infd_bluechan); } if (chan5chan) { G_free(inrast_chan5chan); Rast_close(infd_chan5chan); } if (chan7chan) { G_free(inrast_chan7chan); Rast_close(infd_chan7chan); } G_free(outrast); Rast_close(outfd); if (!strcasecmp(viflag, "ndvi")) { /* apply predefined NDVI color table */ const char *style = "ndvi"; if (G_find_color_rule("ndvi")) { Rast_make_fp_colors(&colors, style, -1.0, 1.0); } else G_fatal_error(_("Unknown color request '%s'"), style); } else { /* Color from -1.0 to +1.0 in grey */ Rast_init_colors(&colors); val1 = -1; val2 = 1; Rast_add_c_color_rule(&val1, 0, 0, 0, &val2, 255, 255, 255, &colors); } Rast_write_colors(result, G_mapset(), &colors); Rast_short_history(result, "raster", &history); Rast_command_history(&history); Rast_write_history(result, &history); exit(EXIT_SUCCESS); }
/* * check_stats() - Check and update statistics * * RETURN: 0 on success / 1 on failure */ int check_stats(const char *name) { RASTER_MAP_TYPE data_type; struct Histogram histogram; struct Categories cats; struct Range range; struct FPRange fprange; int i, histo_num; int cats_ok; int max; data_type = Rast_map_type(name, ""); G_message(_("Updating statistics for [%s]..."), name); if (!do_histogram(name)) return 1; if (Rast_read_histogram(name, "", &histogram) <= 0) return 1; /* Init histogram range */ if (data_type == CELL_TYPE) Rast_init_range(&range); else Rast_init_fp_range(&fprange); G_message(_("Updating histogram range...")); i = histo_num = Rast_get_histogram_num(&histogram); while (i >= 0) { G_percent(i, histo_num, 2); if (data_type == CELL_TYPE) Rast_update_range(Rast_get_histogram_cat(i--, &histogram), &range); else Rast_update_fp_range((DCELL) Rast_get_histogram_cat(i--, &histogram), &fprange); } /* Write histogram range */ if (data_type == CELL_TYPE) Rast_write_range(name, &range); else Rast_write_fp_range(name, &fprange); /* Get category status and max */ cats_ok = (Rast_read_cats(name, "", &cats) >= 0); max = (data_type == CELL_TYPE ? range.max : fprange.max); /* Further category checks */ if (!cats_ok) Rast_init_cats("", &cats); else if (cats.num != max) { cats.num = max; cats_ok = 0; } /* Update categories if needed */ if (!cats_ok) { G_message(_("Updating the number of categories for [%s]..."), name); Rast_write_cats(name, &cats); } Rast_free_histogram(&histogram); Rast_free_cats(&cats); return 0; }
/*! \brief Get GDAL link settings for given raster map \param name map name \param mapset name of mapset \return pointer to GDAL_link structure \return NULL if link not found */ struct GDAL_link *Rast_get_gdal_link(const char *name, const char *mapset) { #ifdef GDAL_LINK GDALDatasetH data; GDALRasterBandH band; GDALDataType type; RASTER_MAP_TYPE req_type; #endif const char *filename; int band_num; struct GDAL_link *gdal; RASTER_MAP_TYPE map_type; FILE *fp; struct Key_Value *key_val; const char *p; DCELL null_val; int hflip, vflip; if (!G_find_raster2(name, mapset)) return NULL; map_type = Rast_map_type(name, mapset); if (map_type < 0) return NULL; fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset); if (!fp) return NULL; key_val = G_fread_key_value(fp); fclose(fp); if (!key_val) return NULL; filename = G_find_key_value("file", key_val); if (!filename) return NULL; p = G_find_key_value("band", key_val); if (!p) return NULL; band_num = atoi(p); if (!band_num) return NULL; p = G_find_key_value("null", key_val); if (!p) return NULL; if (strcmp(p, "none") == 0) Rast_set_d_null_value(&null_val, 1); else null_val = atof(p); hflip = G_find_key_value("hflip", key_val) ? 1 : 0; vflip = G_find_key_value("vflip", key_val) ? 1 : 0; #ifdef GDAL_LINK p = G_find_key_value("type", key_val); if (!p) return NULL; type = atoi(p); switch (type) { case GDT_Byte: case GDT_Int16: case GDT_UInt16: case GDT_Int32: case GDT_UInt32: req_type = CELL_TYPE; break; case GDT_Float32: req_type = FCELL_TYPE; break; case GDT_Float64: req_type = DCELL_TYPE; break; default: return NULL; } if (req_type != map_type) return NULL; Rast_init_gdal(); data = (*pGDALOpen) (filename, GA_ReadOnly); if (!data) return NULL; band = (*pGDALGetRasterBand) (data, band_num); if (!band) { (*pGDALClose) (data); return NULL; } #endif gdal = G_calloc(1, sizeof(struct GDAL_link)); gdal->filename = G_store(filename); gdal->band_num = band_num; gdal->null_val = null_val; gdal->hflip = hflip; gdal->vflip = vflip; #ifdef GDAL_LINK gdal->data = data; gdal->band = band; gdal->type = type; #endif return gdal; }
int main(int argc, char *argv[]) { struct Cell_head cellhd; /*region+header info */ char *mapset; /*mapset name */ int nrows, ncols; int row, col; struct GModule *module; struct Option *input, *output; struct Option *input1, *input2; struct Flag *flag0, *flag1, *flag2; struct Flag *flag3, *flag4, *flag5; struct History history; /*metadata */ /************************************/ char *name; /*input raster name */ char *result; /*output raster name */ /*Prepare new names for output files */ char result0[GNAME_MAX], result1[GNAME_MAX]; char result2[GNAME_MAX], result3[GNAME_MAX]; char result4[GNAME_MAX], result5[GNAME_MAX]; char result6[GNAME_MAX], result7[GNAME_MAX]; char result8[GNAME_MAX], result9[GNAME_MAX]; char result10[GNAME_MAX], result11[GNAME_MAX]; char result12[GNAME_MAX], result13[GNAME_MAX]; char result14[GNAME_MAX]; /*File Descriptors */ int infd[MAXFILES]; int outfd[MAXFILES]; char **names, **ptr; /* For some strange reason infd[0] cannot be used later */ /* So nfiles is initialized with nfiles = 1 */ int nfiles = 1; int i = 0, j = 0; int radiance = 0; void *inrast[MAXFILES]; DCELL *outrast[MAXFILES]; RASTER_MAP_TYPE in_data_type[MAXFILES]; RASTER_MAP_TYPE out_data_type = DCELL_TYPE; /* 0=numbers 1=text */ double gain[MAXFILES], offset[MAXFILES]; double kexo[MAXFILES]; double doy, sun_elevation; /************************************/ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("radiometric conversion")); G_add_keyword(_("radiance")); G_add_keyword(_("reflectance")); G_add_keyword(_("brightness temperature")); G_add_keyword(_("satellite")); G_add_keyword(_("ASTER")); module->description = _("Calculates Top of Atmosphere Radiance/Reflectance/Brightness Temperature from ASTER DN.\n"); /* Define the different options */ input = G_define_standard_option(G_OPT_R_INPUTS); input->description = _("Names of ASTER DN layers (15 layers)"); input1 = G_define_option(); input1->key = "dayofyear"; input1->type = TYPE_DOUBLE; input1->required = YES; input1->gisprompt = "value"; input1->description = _("Day of Year of satellite overpass [0-366]"); input2 = G_define_option(); input2->key = "sun_elevation"; input2->type = TYPE_DOUBLE; input2->required = YES; input2->gisprompt = "value"; input2->description = _("Sun elevation angle (degrees, < 90.0)"); output = G_define_standard_option(G_OPT_R_OUTPUT); output->description = _("Base name of the output layers (will add .x)"); /* Define the different flags */ flag0 = G_define_flag(); flag0->key = 'r'; flag0->description = _("Output is radiance (W/m2)"); flag1 = G_define_flag(); flag1->key = 'a'; flag1->description = _("VNIR is High Gain"); flag2 = G_define_flag(); flag2->key = 'b'; flag2->description = _("SWIR is High Gain"); flag3 = G_define_flag(); flag3->key = 'c'; flag3->description = _("VNIR is Low Gain 1"); flag4 = G_define_flag(); flag4->key = 'd'; flag4->description = _("SWIR is Low Gain 1"); flag5 = G_define_flag(); flag5->key = 'e'; flag5->description = _("SWIR is Low Gain 2"); /********************/ if (G_parser(argc, argv)) exit(EXIT_FAILURE); names = input->answers; ptr = input->answers; doy = atof(input1->answer); sun_elevation = atof(input2->answer); result = output->answer; radiance = (flag0->answer); /********************/ /*Prepare the output file names */ /********************/ sprintf(result0,"%s%s", result, ".1"); sprintf(result1,"%s%s", result, ".2"); sprintf(result2,"%s%s", result, ".3N"); sprintf(result3,"%s%s", result, ".3B"); sprintf(result4,"%s%s", result, ".4"); sprintf(result5,"%s%s", result, ".5"); sprintf(result6,"%s%s", result, ".6"); sprintf(result7,"%s%s", result, ".7"); sprintf(result8,"%s%s", result, ".8"); sprintf(result9,"%s%s", result, ".9"); sprintf(result10,"%s%s", result, ".10"); sprintf(result11,"%s%s", result, ".11"); sprintf(result12,"%s%s", result, ".12"); sprintf(result13,"%s%s", result, ".13"); sprintf(result14,"%s%s", result, ".14"); /********************/ /*Prepare radiance boundaries */ /********************/ int gain_code = 1; for (i = 0; i < MAXFILES; i++) { /*0 - High (Not Applicable for band 10-14: TIR) */ /*1 - Normal */ /*2 - Low 1(Not Applicable for band 10-14: TIR) */ /*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */ if (flag1->answer && i <= 3) gain_code = 0; if (flag2->answer && i >= 4 && i <= 9) gain_code = 0; if (flag3->answer && i <= 3) gain_code = 2; if (flag4->answer && i >= 4 && i <= 9) gain_code = 2; if (flag5->answer && i >= 4 && i <= 9) gain_code = 3; gain[i] = gain_aster(i, gain_code); /* Reset to NORMAL GAIN */ gain_code = 1; } /********************/ /*Prepare sun exo-atm irradiance */ /********************/ kexo[0] = KEXO1; kexo[1] = KEXO2; kexo[2] = KEXO3; kexo[3] = KEXO3; kexo[4] = KEXO4; kexo[5] = KEXO5; kexo[6] = KEXO6; kexo[7] = KEXO7; kexo[8] = KEXO8; kexo[9] = KEXO9; /********************/ /********************/ for (; *ptr != NULL; ptr++) { if (nfiles > MAXFILES) G_fatal_error(_("Too many input maps. Only %d allowed."), MAXFILES); name = *ptr; /* Allocate input buffer */ in_data_type[nfiles-1] = Rast_map_type(name, ""); /* For some strange reason infd[0] cannot be used later */ /* So nfiles is initialized with nfiles = 1 */ infd[nfiles] = Rast_open_old(name, ""); Rast_get_cellhd(name, "", &cellhd); inrast[nfiles-1] = Rast_allocate_buf(in_data_type[nfiles-1]); nfiles++; } nfiles--; if (nfiles < MAXFILES) G_fatal_error(_("The input band number should be 15")); /***************************************************/ /* Allocate output buffer, use input map data_type */ nrows = Rast_window_rows(); ncols = Rast_window_cols(); out_data_type = DCELL_TYPE; for (i = 0; i < MAXFILES; i++) outrast[i] = Rast_allocate_buf(out_data_type); outfd[1] = Rast_open_new(result0, 1); outfd[2] = Rast_open_new(result1, 1); outfd[3] = Rast_open_new(result2, 1); outfd[4] = Rast_open_new(result3, 1); outfd[5] = Rast_open_new(result4, 1); outfd[6] = Rast_open_new(result5, 1); outfd[7] = Rast_open_new(result6, 1); outfd[8] = Rast_open_new(result7, 1); outfd[9] = Rast_open_new(result8, 1); outfd[10] = Rast_open_new(result9, 1); outfd[11] = Rast_open_new(result10, 1); outfd[12] = Rast_open_new(result11, 1); outfd[13] = Rast_open_new(result12, 1); outfd[14] = Rast_open_new(result13, 1); outfd[15] = Rast_open_new(result14, 1); /* Process pixels */ DCELL dout[MAXFILES]; DCELL d[MAXFILES]; for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); /* read input map */ for (i = 1; i <= MAXFILES; i++) Rast_get_row(infd[i], inrast[i-1], row, in_data_type[i-1]); /*process the data */ for (col = 0; col < ncols; col++) { for (i = 0; i < MAXFILES; i++) { switch (in_data_type[i]) { case CELL_TYPE: d[i] = (double)((CELL *) inrast[i])[col]; break; case FCELL_TYPE: d[i] = (double)((FCELL *) inrast[i])[col]; break; case DCELL_TYPE: d[i] = (double)((DCELL *) inrast[i])[col]; break; } /* if radiance mode or Thermal band */ if (radiance || i >= 10) { dout[i] = gain[i] * (d[i] - 1.0); } /* if reflectance default mode and Not Thermal Band */ else { dout[i] = gain[i] * (d[i] - 1.0); dout[i] = rad2ref_aster(dout[i], doy, sun_elevation, kexo[i]); } outrast[i][col] = dout[i]; } } for (i = 1; i <= MAXFILES; i++) Rast_put_row(outfd[i], outrast[i-1], out_data_type); } for (i = 1; i <= MAXFILES; i++) { G_free(inrast[i-1]); Rast_close(infd[i]); G_free(outrast[i-1]); Rast_close(outfd[i]); } exit(EXIT_SUCCESS); }
int null_distance(const char *name1, const char *name2, int *zerro_row, int *zerro_col) { RASTER_MAP_TYPE maptype1, maptype2; const char *mapset; int mapd1, mapd2; void *inrast1, *inrast2; int nrows, ncols, row, col; void *cell1, *cell2; /* NOTE: no need to controll, if the map exists. it should be checked in edge.c */ mapset = G_find_raster2(name1, ""); maptype1 = Rast_map_type(name1, mapset); mapd1 = Rast_open_old(name1, mapset); inrast1 = Rast_allocate_buf(maptype1); mapset = G_find_raster2(name2, ""); maptype2 = Rast_map_type(name2, mapset); mapd2 = Rast_open_old(name2, mapset); inrast2 = Rast_allocate_buf(maptype2); G_message(_("Reading maps <%s,%s> while finding 0 distance ..."), name1, name2); ncols = Rast_window_cols(); nrows = Rast_window_rows(); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_row(mapd1, inrast1, row, maptype1); Rast_get_row(mapd2, inrast2, row, maptype2); for (col = 0; col < ncols; col++) { /* first raster */ switch (maptype1) { case CELL_TYPE: cell1 = ((CELL **) inrast1)[col]; break; case FCELL_TYPE: cell1 = ((FCELL **) inrast1)[col]; break; case DCELL_TYPE: cell1 = ((DCELL **) inrast1)[col]; break; } /* second raster */ switch (maptype2) { case CELL_TYPE: cell2 = ((CELL **) inrast2)[col]; break; case FCELL_TYPE: cell2 = ((FCELL **) inrast2)[col]; break; case DCELL_TYPE: cell2 = ((DCELL **) inrast2)[col]; break; } if (!Rast_is_null_value(&cell1, maptype1) && !Rast_is_null_value(&cell2, maptype2)) { *zerro_row = row; *zerro_col = col; /* memory cleanup */ G_free(inrast1); G_free(inrast2); /* closing raster maps */ Rast_close(mapd1); Rast_close(mapd2); return 1; } } } /* memory cleanup */ G_free(inrast1); G_free(inrast2); /* closing raster maps */ Rast_close(mapd1); Rast_close(mapd2); return 0; }
int main(int argc, char *argv[]) { struct Categories cats; struct FPRange range; DCELL min, max; RASTER_MAP_TYPE map_type; char buf[1024]; RULE *rules, *tail; int any; const char *old_mapset; FILE *srcfp; int tty; struct GModule *module; struct { struct Option *input, *output, *title, *rules; } parm; /* any interaction must run in a term window */ G_putenv("GRASS_UI_TERM", "1"); G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("reclassification")); module->label = _("Reclassify raster map based on category values."); module->description = _("Creates a new raster map whose category values are based " "upon a reclassification of the categories in an existing " "raster map."); parm.input = G_define_standard_option(G_OPT_R_INPUT); parm.input->description = _("Name of raster map to be reclassified"); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.rules = G_define_standard_option(G_OPT_F_INPUT); parm.rules->key = "rules"; parm.rules->label = _("File containing reclass rules"); parm.rules->description = _("'-' for standard input"); parm.title = G_define_option(); parm.title->key = "title"; parm.title->required = NO; parm.title->type = TYPE_STRING; parm.title->description = _("Title for output raster map"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); old_mapset = G_find_raster2(parm.input->answer, ""); if (old_mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), parm.input->answer); if (strcmp(parm.input->answer, parm.output->answer) == 0 && strcmp(old_mapset, G_mapset()) == 0) G_fatal_error(_("Input map can NOT be the same as output map")); srcfp = stdin; if (strcmp(parm.rules->answer, "-") != 0) { srcfp = fopen(parm.rules->answer, "r"); if (!srcfp) G_fatal_error(_("Cannot open rules file <%s>"), parm.rules->answer); } tty = isatty(fileno(srcfp)); Rast_init_cats("", &cats); map_type = Rast_map_type(parm.input->answer, old_mapset); Rast_read_fp_range(parm.input->answer, old_mapset, &range); Rast_get_fp_range_min_max(&range, &min, &max); rules = tail = NULL; any = 0; if (tty) { fprintf(stderr, _("Enter rule(s), \"end\" when done, \"help\" if you need it\n")); if (map_type == FCELL_TYPE) fprintf(stderr, _("FCELL: Data range is %.7g to %.7g\n"), (double)min, (double)max); else if (map_type == DCELL_TYPE) fprintf(stderr, _("DCELL: Data range is %.15g to %.15g\n"), (double)min, (double)max); else fprintf(stderr, _("CELL: Data range is %ld to %ld\n"), (long)min, (long)max); } while (input(srcfp, tty, buf)) { switch (parse(buf, &rules, &tail, &cats)) { case -1: if (tty) { fprintf(stderr, _("Illegal reclass rule -")); fprintf(stderr, _(" ignored\n")); } else { strcat(buf, _(" - invalid reclass rule")); G_fatal_error("%s", buf); } break; case 0: break; default: any = 1; break; } } if (!any) { if (tty) G_fatal_error(_("No rules specified. Raster map <%s> not created"), parm.output->answer); else G_fatal_error(_("No rules specified")); } reclass(parm.input->answer, old_mapset, parm.output->answer, rules, &cats, parm.title->answer); exit(EXIT_SUCCESS); }