Esempio n. 1
0
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;
}
Esempio n. 2
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
	



}
Esempio n. 3
0
File: range.c Progetto: caomw/grass
/*!
 * \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;
}
Esempio n. 4
0
File: range.c Progetto: caomw/grass
/*!
 * \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);
}
Esempio n. 5
0
File: main.c Progetto: caomw/grass
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);
    }
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
File: main.c Progetto: caomw/grass
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
File: range.c Progetto: caomw/grass
/*!
 * \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;
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
/*
 * 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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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;
}
Esempio n. 16
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);
}