Example #1
0
int support(char **names,
	    struct Cell_stats *statf, int nfiles,
	    struct Categories *cats,
	    int *cats_ok,
	    struct Colors *colr, int *colr_ok, RASTER_MAP_TYPE out_type)
{
    int i;
    struct Categories pcats;
    struct Colors pcolr;
    CELL n;
    long count;
    int red, grn, blu;
    int do_cats, do_colr;

    *cats_ok = 1;
    *colr_ok = 1;
    if (Rast_read_cats(names[0], "", cats) < 0)
	*cats_ok = 0;
    G_suppress_warnings(1);
    if (Rast_read_colors(names[0], "", colr) < 0)
	*colr_ok = 0;
    G_suppress_warnings(0);

    if (*cats_ok == 0 && *colr_ok == 0)
	return 0;

    for (i = 1; i < nfiles; i++) {
	do_cats = *cats_ok && (Rast_read_cats(names[i], "", &pcats) >= 0);
	G_suppress_warnings(1);
	do_colr = *colr_ok && (Rast_read_colors(names[i], "", &pcolr) >= 0);
	G_suppress_warnings(0);
	if (!do_cats && !do_colr)
	    continue;
	if (out_type == CELL_TYPE) {
	    Rast_rewind_cell_stats(statf + i);
	    while (Rast_next_cell_stat(&n, &count, statf + i))
		if (n && !Rast_find_cell_stat(n, &count, statf)) {
		    if (do_cats) {
			Rast_update_cell_stats(&n, 1, statf);
			Rast_set_c_cat(&n, &n, Rast_get_c_cat((CELL *) &n, &pcats), cats);
		    }
		    if (do_colr) {
			Rast_get_c_color(&n, &red, &grn, &blu, &pcolr);
			Rast_set_c_color(n, red, grn, blu, colr);
		    }
		}
	}
	/* else the color will be the color of the first map */

	if (do_cats)
	    Rast_free_cats(&pcats);
	if (do_colr)
	    /* otherwise this memory is used in colr pointer */
	    Rast_free_colors(&pcolr);
    }
    return 1;
}
Example #2
0
static void write_support_files(int xtile, int ytile, int overlap)
{
    char name[GNAME_MAX];
    struct Cell_head cellhd;
    char title[64];
    struct History history;
    struct Colors colors;
    struct Categories cats;

    sprintf(name, "%s-%03d-%03d", parm.rastout->answer, ytile, xtile);

    Rast_get_cellhd(name, G_mapset(), &cellhd);

    cellhd.north = src_w.north - ytile * dst_w.rows * src_w.ns_res;
    cellhd.south = cellhd.north - (dst_w.rows + 2 * overlap) * src_w.ns_res;
    cellhd.west = src_w.west + xtile * dst_w.cols * src_w.ew_res;
    cellhd.east = cellhd.west + (dst_w.cols + 2 * overlap) * src_w.ew_res;

    Rast_put_cellhd(name, &cellhd);

    /* copy cats from source map */
    if (Rast_read_cats(parm.rastin->answer, "", &cats) < 0)
	G_fatal_error(_("Unable to read cats for %s"),
		      parm.rastin->answer);
    Rast_write_cats(name, &cats);

    /* record map metadata/history info */
    G_debug(1, "Tile %d,%d of %s: writing %s", xtile, ytile, parm.rastin->answer, name);
    sprintf(title, "Tile %d,%d of %s", xtile, ytile, parm.rastin->answer);
    Rast_put_cell_title(name, title);

    Rast_short_history(name, "raster", &history);
    Rast_set_history(&history, HIST_DATSRC_1, parm.rastin->answer);
    Rast_command_history(&history);
    Rast_write_history(name, &history);

    /* copy color table from source map */
    if (Rast_read_colors(parm.rastin->answer, "", &colors) < 0)
	G_fatal_error(_("Unable to read color table for %s"),
		      parm.rastin->answer);
    if (map_type != CELL_TYPE)
	Rast_mark_colors_as_fp(&colors);
    Rast_write_colors(name, G_mapset(), &colors);
}
Example #3
0
int parse_layer(char *s)
{
    char name[GNAME_MAX];
    const char *mapset;
    struct FPRange fp_range;
    int n;

    strcpy(name, s);
    mapset = G_find_raster2(name, "");

    if (mapset == NULL)
	G_fatal_error(_("Raster map <%s> not found"), s);

    n = nlayers++;
    layers = (LAYER *) G_realloc(layers, nlayers * sizeof(LAYER));
    is_fp = (int *)G_realloc(is_fp, (nlayers + 1) * sizeof(int));
    DMAX = (DCELL *) G_realloc(DMAX, (nlayers + 1) * sizeof(DCELL));
    DMIN = (DCELL *) G_realloc(DMIN, (nlayers + 1) * sizeof(DCELL));
    if (!as_int)
	is_fp[n] = Rast_map_is_fp(name, mapset);
    else
	is_fp[n] = 0;
    if (is_fp[n]) {
	if (Rast_read_fp_range(name, mapset, &fp_range) < 0)
	    G_fatal_error(_("Unable to read fp range for raster map <%s>"),
			  name);
	Rast_get_fp_range_min_max(&fp_range, &DMIN[n], &DMAX[n]);
    }

    layers[n].name = G_store(name);
    layers[n].mapset = mapset;
    if (Rast_read_cats(name, mapset, &layers[n].labels) < 0)
	G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
		      name, mapset);

    return 0;
}
Example #4
0
File: main.c Project: 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);
}
Example #5
0
int main(int argc, char **argv)
{
    int text_height;
    int text_width;
    struct Categories cats;
    struct Range range;
    struct Colors pcolors;
    char title[GNAME_MAX];
    double tt, tb, tl, tr;
    double t, b, l, r;
    struct GModule *module;
    struct Option *opt1;
    struct Option *opt2, *bg_opt;
    struct Option *opt4;
    struct Option *opt5;
    struct Flag *flag1;
    struct Flag *flag2;
    struct Flag *flag3;


    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("histogram"));
    G_add_keyword(_("statistics"));
    module->description =
	_("Displays a histogram in the form of a pie or bar chart "
	  "for a user-specified raster map.");

    opt1 = G_define_standard_option(G_OPT_R_MAP);
    opt1->description = _("Raster map for which histogram will be displayed");

    opt4 = G_define_option();
    opt4->key = "style";
    opt4->description = _("Indicate if a pie or bar chart is desired");
    opt4->type = TYPE_STRING;
    opt4->required = NO;
    opt4->options = "pie,bar";
    opt4->answer = "bar";

    /* The color option specifies the color for the labels, tic-marks,
     * and borders of the chart. */
    opt2 = G_define_standard_option(G_OPT_C);
    opt2->label = _("Color for text and axes");

    bg_opt = G_define_standard_option(G_OPT_CN);
    bg_opt->key = "bgcolor";
    bg_opt->label = _("Background color");
    bg_opt->answer = DEFAULT_BG_COLOR;

#ifdef CAN_DO_AREAS
    opt3 = G_define_option();
    opt3->key = "type";
    opt3->description =
	_("Indicate if cell counts or map areas should be displayed");
    opt3->type = TYPE_STRING;
    opt3->required = NO;
    opt3->answer = "count";
    opt3->options = "count,area";
#endif

    opt5 = G_define_option();
    opt5->key = "nsteps";
    opt5->description =
	_("Number of steps to divide the data range into (fp maps only)");
    opt5->type = TYPE_INTEGER;
    opt5->required = NO;
    opt5->answer = "255";

    flag1 = G_define_flag();
    flag1->key = 'n';
    flag1->description = _("Display information for null cells");

    flag3 = G_define_flag();
    flag3->key = 'c';
    flag3->description =
	_("Report for ranges defined in cats file (fp maps only)");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    map_name = opt1->answer;

    color = D_parse_color(opt2->answer, FALSE);

    type = COUNT;
#ifdef CAN_DO_AREAS
    if (strcmp(opt3->answer, "count") == 0)
	type = COUNT;
    else
	type = AREA;
#endif

    if (strcmp(opt4->answer, "bar") == 0)
	style = BAR;
    else
	style = PIE;

    if (sscanf(opt5->answer, "%d", &nsteps) != 1)
	G_fatal_error(_("Invalid number of steps: %s"), opt5->answer);

    cat_ranges = flag3->answer;

    if (cat_ranges && nsteps != 255)
	G_warning(_("When -C flag is set, the nsteps argument is ignored"));

    nodata = flag1->answer;

    if (Rast_read_colors(map_name, "", &pcolors) == -1)
	G_fatal_error(_("Color file for <%s> not available"), map_name);

    if (Rast_read_cats(map_name, "", &cats) == -1)
	G_fatal_error(_("Category file for <%s> not available"), map_name);

    if (Rast_read_range(map_name, "", &range) == -1)
	G_fatal_error(_("Range information for <%s> not available"),
		      map_name);

    /* get the distribution statistics */

    get_stats(map_name, &dist_stats);

    /* set up the graphics driver and initialize its color-table */

    D_open_driver();
    
    D_setup_unity(0);			/* 0 = don't clear frame */
    D_get_src(&t, &b, &l, &r);

    /* clear the frame, if requested to do so */
    if (strcmp(bg_opt->answer, "none") != 0)
	D_erase(bg_opt->answer);

    /* draw a title for */
    sprintf(title, "%s", map_name);
    text_height = (b - t) * 0.05;
    text_width = (r - l) * 0.05 * 0.50;
    D_text_size(text_width, text_height);
    D_get_text_box(title, &tt, &tb, &tl, &tr);
    D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2,
	      t + (b - t) * 0.07);
    D_use_color(color);
    D_text(title);

    /* plot the distributrion statistics */
    if (style == PIE)
	pie(&dist_stats, &pcolors);
    else
	bar(&dist_stats, &pcolors);

    D_save_command(G_recreate_command());
    D_close_driver();

    exit(EXIT_SUCCESS);
}
Example #6
0
int main(int argc, char **argv)
{
    struct Cell_head window;
    struct Categories cats;
    struct GModule *module;
    struct Option *opt1, *opt2, *opt3;
    struct Flag *fancy_mode, *simple_mode, *draw;
    char *tmpfile;
    FILE *fp;

    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("cartography"));
    module->description =
	_("Create a TITLE for a raster map in a form suitable "
	  "for display with d.text.");

    opt1 = G_define_standard_option(G_OPT_R_MAP);

    opt2 = G_define_option();
    opt2->key = "color";
    opt2->type = TYPE_STRING;
    opt2->answer = DEFAULT_FG_COLOR;
    opt2->required = NO;
    opt2->gisprompt = "old_color,color,color";
    opt2->description = _("Sets the text color");

    opt3 = G_define_option();
    opt3->key = "size";
    opt3->type = TYPE_DOUBLE;
    opt3->answer = "4.0";
    opt3->options = "0-100";
    opt3->description =
	_("Sets the text size as percentage of the frame's height");

    draw = G_define_flag();
    draw->key = 'd';
    draw->description = _("Draw title on current display");

    fancy_mode = G_define_flag();
    fancy_mode->key = 'f';
    fancy_mode->description = _("Do a fancier title");

    /* currently just title, but it doesn't have to be /that/ simple */
    simple_mode = G_define_flag();
    simple_mode->key = 's';
    simple_mode->description = _("Do a simple title");


    /* Check command line */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    map_name = opt1->answer;

    color = opt2->answer;

    if (opt3->answer != NULL)
	sscanf(opt3->answer, "%f", &size);

    type = fancy_mode->answer ? FANCY : NORMAL;

    if (fancy_mode->answer && simple_mode->answer)
	G_fatal_error(_("Title can be fancy or simple, not both"));

    if (!strlen(map_name))
	G_fatal_error(_("No map name given"));

    Rast_get_cellhd(map_name, "", &window);

    if (Rast_read_cats(map_name, "", &cats) == -1)
	G_fatal_error(_("Unable to read category file of raster map <%s>"),
		      map_name);


    if (draw->answer) {
	tmpfile = G_convert_dirseps_to_host(G_tempfile());
	if (!(fp = fopen(tmpfile, "w")))
	    G_fatal_error(_("Unable to open temporary file <%s>"), tmpfile);
    }
    else
	fp = stdout;


    if (type == NORMAL)
	normal(&window, &cats, simple_mode->answer, fp);
    else
	fancy(&window, &cats, fp);


    if (draw->answer) {
	char inarg[GPATH_MAX];
	fclose(fp);
	sprintf(inarg, "input=%s", tmpfile);
	G_spawn("d.text", "d.text", inarg, NULL);
	unlink(tmpfile);
	/* note a tmp file will remain, created by d.text so it can survive d.redraw */
    }

    exit(EXIT_SUCCESS);
}
Example #7
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *in_opt, *out_opt, *feature_opt, *column_name;
    struct Flag *smooth_flg, *value_flg, *z_flg, *no_topol;
    int feature;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("conversion"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("vectorization"));
    module->description = _("Converts a raster map into a vector map.");

    in_opt = G_define_standard_option(G_OPT_R_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    feature_opt = G_define_standard_option(G_OPT_V_TYPE);
    feature_opt->required = YES;
    feature_opt->multiple = NO;
    feature_opt->options = "point,line,area";
    feature_opt->answer = NULL;

    column_name = G_define_standard_option(G_OPT_DB_COLUMN);
    column_name->label = _("Name of attribute column to store value");
    column_name->description = _("Name must be SQL compliant");
    column_name->answer = "value";

    smooth_flg = G_define_flag();
    smooth_flg->key = 's';
    smooth_flg->description = _("Smooth corners of area features");

    value_flg = G_define_flag();
    value_flg->key = 'v';
    value_flg->description =
	_("Use raster values as categories instead of unique sequence (CELL only)");
    value_flg->guisection = _("Attributes");

    z_flg = G_define_flag();
    z_flg->key = 'z';
    z_flg->label = _("Write raster values as z coordinate");
    z_flg->description = _("Table is not created. "
			   "Currently supported only for points.");
    z_flg->guisection = _("Attributes");

    no_topol = G_define_flag();
    no_topol->key = 'b';
    no_topol->label = _("Do not build vector topology");
    no_topol->description = _("Recommended for massive point conversion");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    feature = Vect_option_to_types(feature_opt);
    smooth_flag = (smooth_flg->answer) ? SMOOTH : NO_SMOOTH;
    value_flag = value_flg->answer;

    if (z_flg->answer && (feature != GV_POINT))
	G_fatal_error(_("z flag is supported only for points"));

    /* Open files */
    input_fd = Rast_open_old(in_opt->answer, "");

    data_type = Rast_get_map_type(input_fd);
    data_size = Rast_cell_size(data_type);
    G_get_window(&cell_head);

    if (value_flag && data_type != CELL_TYPE) {
	G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be written to the table."));
	value_flag = 0;
    }

    if (z_flg->answer)
	Vect_open_new(&Map, out_opt->answer, 1);
    else
	Vect_open_new(&Map, out_opt->answer, 0);

    Vect_hist_command(&Map);

    Cats = Vect_new_cats_struct();

    /* Open category labels */
    if (data_type == CELL_TYPE) {
	if (0 == Rast_read_cats(in_opt->answer, "", &RastCats))
	    has_cats = 1;
    }
    else
	has_cats = 0;

    db_init_string(&sql);
    db_init_string(&label);

    /* Create table */
    if ((feature & (GV_AREA | GV_POINT | GV_LINE)) &&
	(!value_flag || (value_flag && has_cats)) && !(z_flg->answer)) {
	char buf[1000];

	Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	driver =
	    db_start_driver_open_database(Fi->driver,
					  Vect_subst_var(Fi->database, &Map));
	if (driver == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);

	/* Create new table */
	db_zero_string(&sql);
	sprintf(buf, "create table %s ( cat integer", Fi->table);
	db_append_string(&sql, buf);

	if (!value_flag) {	/* add value to the table */
	    if (data_type == CELL_TYPE) {
		db_append_string(&sql, ", ");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " integer");
	    } else {
		db_append_string(&sql, ",");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " double precision");
	    }
	}

	if (has_cats) {
	    int i, len;
	    int clen = 0;

	    /* Get maximum column length */
	    for (i = 0; i < RastCats.ncats; i++) {
		len = strlen(RastCats.labels[i]);
		if (len > clen)
		    clen = len;
	    }
	    clen += 10;

	    sprintf(buf, ", label varchar(%d)", clen);
	    db_append_string(&sql, buf);
	}

	db_append_string(&sql, ")");

	G_debug(3, db_get_string(&sql));

	if (db_execute_immediate(driver, &sql) != DB_OK)
	    G_fatal_error(_("Unable to create table: %s"),
			  db_get_string(&sql));

	if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	    G_warning(_("Unable to create index"));

	if (db_grant_on_table
	    (driver, Fi->table, DB_PRIV_SELECT,
	     DB_GROUP | DB_PUBLIC) != DB_OK)
	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
			  Fi->table);

	db_begin_transaction(driver);

    }
    else {
	driver = NULL;
    }

    /* init variables for lines and areas */
    first_read = 1;
    last_read = 0;
    direction = FORWARD;
    row_length = cell_head.cols;
    n_rows = cell_head.rows;
    row_count = 0;

    if (feature == GV_LINE) {
	alloc_lines_bufs(row_length + 2);
	extract_lines();
    }
    else if (feature == GV_AREA) {
	alloc_areas_bufs(row_length + 2);
	extract_areas();
    }
    else {			/* GV_POINT */

	extract_points(z_flg->answer);
    }

    Rast_close(input_fd);

    if (!no_topol->answer)
	Vect_build(&Map);


    /* insert cats and optionally labels if raster cats were used */
    if (driver && value_flag) {
	char buf[1000];
	int c, i, cat, fidx, ncats, lastcat, tp, id;

	fidx = Vect_cidx_get_field_index(&Map, 1);
	if (fidx >= 0) {
	    ncats = Vect_cidx_get_num_cats_by_index(&Map, fidx);
	    lastcat = -1;

	    for (c = 0; c < ncats; c++) {
		Vect_cidx_get_cat_by_index(&Map, fidx, c, &cat, &tp, &id);

		if (lastcat == cat)
		    continue;

		/* find label, slow -> TODO faster */
		db_set_string(&label, "");
		for (i = 0; i < RastCats.ncats; i++) {
		    if (cat == (int)RastCats.q.table[i].dLow) {	/* cats are in dLow/High not in cLow/High !!! */
			db_set_string(&label, RastCats.labels[i]);
			db_double_quote_string(&label);
			break;
		    }
		}
		G_debug(3, "cat = %d label = %s", cat, db_get_string(&label));

		sprintf(buf, "insert into %s values ( %d, '%s')", Fi->table,
			cat, db_get_string(&label));
		db_set_string(&sql, buf);
		G_debug(3, db_get_string(&sql));

		if (db_execute_immediate(driver, &sql) != DB_OK)
		    G_fatal_error(_("Unable to insert into table: %s"),
				  db_get_string(&sql));

		lastcat = cat;
	    }
	}
    }

    if (has_cats)
	Rast_free_cats(&RastCats);

    if (driver != NULL) {
	db_commit_transaction(driver);
	db_close_database_shutdown_driver(driver);
    }

    Vect_close(&Map);
    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}
Example #8
0
int main(int argc, char *argv[])
{
    int *fd;
    char **names;
    char **ptr;
    char *name;

    /* flags */
    int raw_data;
    int with_coordinates;
    int with_xy;
    int with_percents;
    int with_counts;
    int with_areas;
    int with_labels;

    /* printf format */
    char fmt[20];
    int dp;
    struct Range range;
    struct FPRange fp_range;
    struct Quant q;
    CELL min, max, null_set = 0;
    DCELL dmin, dmax;
    struct GModule *module;
    struct
    {
	struct Flag *A;		/* print averaged values instead of intervals */
	struct Flag *a;		/* area */
	struct Flag *c;		/* cell counts */
	struct Flag *p;		/* percents */
	struct Flag *l;		/* with labels */
	struct Flag *q;		/* quiet */
	struct Flag *n;		/* Suppress reporting of any NULLs */
	struct Flag *N;		/* Suppress reporting of NULLs when 
				   all values are NULL */
	struct Flag *one;	/* one cell per line */
	struct Flag *x;		/*    with row/col */
	struct Flag *g;		/*    with east/north */
	struct Flag *i;		/* use quant rules for fp map, i.e. read it as int */
	struct Flag *r;		/*    raw output: when nsteps option is used,
				   report indexes of ranges instead of ranges
				   themselves; when -C (cats) option is used
				   reports indexes of fp ranges = ind. of labels */
	struct Flag *C;		/* report stats for labeled ranges in cats files */
    } flag;
    struct
    {
	struct Option *cell;
	struct Option *fs;
	struct Option *nv;
	struct Option *output;
	struct Option *nsteps;	/* divide data range into nsteps and report stats
				   for these ranges: only for fp maps
				   NOTE: when -C flag is used, and there are 
				   explicit fp ranges in cats or when the map 
				   is int, nsteps is ignored */
    } option;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("statistics"));
    module->description =
	_("Generates area statistics for raster map layers.");

    /* Define the different options */

    option.cell = G_define_standard_option(G_OPT_R_INPUTS);

    option.output = G_define_standard_option(G_OPT_F_OUTPUT);
    option.output->required = NO;
    option.output->description =
	_("Name for output file (if omitted or \"-\" output to stdout)");

    option.fs = G_define_standard_option(G_OPT_F_SEP);
    option.fs->key_desc = "character|space|tab";
    option.fs->answer = "space";
    option.fs->description = _("Output field separator");

    option.nv = G_define_option();
    option.nv->key = "nv";
    option.nv->type = TYPE_STRING;
    option.nv->required = NO;
    option.nv->multiple = NO;
    option.nv->answer = "*";
    option.nv->description = _("String representing no data cell value");

    option.nsteps = G_define_option();
    option.nsteps->key = "nsteps";
    option.nsteps->type = TYPE_INTEGER;
    option.nsteps->required = NO;
    option.nsteps->multiple = NO;
    option.nsteps->answer = "255";
    option.nsteps->description =
	_("Number of fp subranges to collect stats from");

    /* Define the different flags */

    flag.one = G_define_flag();
    flag.one->key = '1';
    flag.one->description = _("One cell (range) per line");

    flag.A = G_define_flag();
    flag.A->key = 'A';
    flag.A->description = _("Print averaged values instead of intervals");
    flag.A->guisection = _("Print");

    flag.a = G_define_flag();
    flag.a->key = 'a';
    flag.a->description = _("Print area totals");
    flag.a->guisection = _("Print");

    flag.c = G_define_flag();
    flag.c->key = 'c';
    flag.c->description = _("Print cell counts");
    flag.c->guisection = _("Print");

    flag.p = G_define_flag();
    flag.p->key = 'p';
    flag.p->description =
	_("Print APPROXIMATE percents (total percent may not be 100%)");
    flag.p->guisection = _("Print");

    flag.l = G_define_flag();
    flag.l->key = 'l';
    flag.l->description = _("Print category labels");
    flag.l->guisection = _("Print");

    flag.g = G_define_flag();
    flag.g->key = 'g';
    flag.g->description = _("Print grid coordinates (east and north)");
    flag.g->guisection = _("Print");

    flag.x = G_define_flag();
    flag.x->key = 'x';
    flag.x->description = _("Print x and y (column and row)");
    flag.x->guisection = _("Print");

    flag.r = G_define_flag();
    flag.r->key = 'r';
    flag.r->description = _("Print raw indexes of fp ranges (fp maps only)");
    flag.r->guisection = _("Print");

    flag.n = G_define_flag();
    flag.n->key = 'n';
    flag.n->description = _("Suppress reporting of any NULLs");

    flag.N = G_define_flag();
    flag.N->key = 'N';
    flag.N->description =
	_("Suppress reporting of NULLs when all values are NULL");

    flag.C = G_define_flag();
    flag.C->key = 'C';
    flag.C->description = _("Report for cats fp ranges (fp maps only)");

    flag.i = G_define_flag();
    flag.i->key = 'i';
    flag.i->description = _("Read fp map as integer (use map's quant rules)");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    name = option.output->answer;
    if (name != NULL && strcmp(name, "-") != 0) {
	if (NULL == freopen(name, "w", stdout)) {
	    G_fatal_error(_("Unable to open file <%s> for writing"), name);
	}
    }

    sscanf(option.nsteps->answer, "%d", &nsteps);
    if (nsteps <= 0) {
	G_warning(_("'%s' must be greater than zero; using %s=255"),
		  option.nsteps->key, option.nsteps->key);
	nsteps = 255;
    }
    cat_ranges = flag.C->answer;

    averaged = flag.A->answer;
    raw_output = flag.r->answer;
    as_int = flag.i->answer;
    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    fd = NULL;
    nfiles = 0;
    dp = -1;

    with_percents = flag.p->answer;
    with_counts = flag.c->answer;
    with_areas = flag.a->answer;
    with_labels = flag.l->answer;

    no_nulls = flag.n->answer;
    no_nulls_all = flag.N->answer;
    no_data_str = option.nv->answer;

    raw_data = flag.one->answer;
    with_coordinates = flag.g->answer;
    with_xy = flag.x->answer;
    if (with_coordinates || with_xy)
	raw_data = 1;

    /* get field separator */
    strcpy(fs, " ");
    if (option.fs->answer) {
	if (strcmp(option.fs->answer, "space") == 0)
	    *fs = ' ';
	else if (strcmp(option.fs->answer, "tab") == 0)
	    *fs = '\t';
	else if (strcmp(option.fs->answer, "\\t") == 0)
	    *fs = '\t';
	else
	    *fs = *option.fs->answer;
    }


    /* open all raster maps */
    if (option.cell->answers[0] == NULL)
	G_fatal_error(_("Raster map not found"));

    names = option.cell->answers;
    ptr = option.cell->answers;

    for (; *ptr != NULL; ptr++) {
	name = *ptr;
	fd = (int *)G_realloc(fd, (nfiles + 1) * sizeof(int));
	is_fp = (int *)G_realloc(is_fp, (nfiles + 1) * sizeof(int));
	DMAX = (DCELL *) G_realloc(DMAX, (nfiles + 1) * sizeof(DCELL));
	DMIN = (DCELL *) G_realloc(DMIN, (nfiles + 1) * sizeof(DCELL));

	fd[nfiles] = Rast_open_old(name, "");
	if (!as_int)
	    is_fp[nfiles] = Rast_map_is_fp(name, "");
	else {
	    is_fp[nfiles] = 0;
	    if (cat_ranges || nsteps != 255)
		G_warning(_("Raster map <%s> is reading as integer map! "
			    "Flag '-%c' and/or '%s' option will be ignored."),
			  name, flag.C->key, option.nsteps->key);
	}
	if (with_labels || (cat_ranges && is_fp[nfiles])) {
	    labels = (struct Categories *)
		G_realloc(labels, (nfiles + 1) * sizeof(struct Categories));
	    if (Rast_read_cats(name, "", &labels[nfiles]) < 0)
		Rast_init_cats("", &labels[nfiles]);
	}
	if (is_fp[nfiles])
	    /* floating point map */
	{
	    Rast_quant_init(&q);
	    if (cat_ranges) {
		if (!Rast_quant_nof_rules(&labels[nfiles].q)) {
		    G_warning(_("Cats for raster map <%s> are either missing or have no explicit labels. "
			       "Using %s=%d."),
			      name, option.nsteps->key, nsteps);
		    cat_ranges = 0;
		}
		else if (nsteps != 255)
		    G_warning(_("Flag '-%c' was given, using cats fp ranges of raster map <%s>, "
			       "ignoring '%s' option"),
			      flag.C->key, name, option.nsteps->key);
	    }
	    if (!cat_ranges) {	/* DO NOT use else here, cat_ranges can change */
		if (Rast_read_fp_range(name, "", &fp_range) < 0)
		    G_fatal_error(_("Unable to read fp range of raster map <%s>"),
				  name);
		Rast_get_fp_range_min_max(&fp_range, &DMIN[nfiles],
				       &DMAX[nfiles]);
		G_debug(3, "file %2d: dmin=%f  dmax=%f", nfiles, DMIN[nfiles], 
			DMAX[nfiles]);

		Rast_quant_add_rule(&q, DMIN[nfiles], DMAX[nfiles], 1, nsteps+1);

		/* set the quant rules for reading the map */
		Rast_set_quant_rules(fd[nfiles], &q);
		Rast_quant_get_limits(&q, &dmin, &dmax, &min, &max);
		G_debug(2, "overall: dmin=%f  dmax=%f,  qmin=%d  qmax=%d",
			dmin, dmax, min, max);

		Rast_quant_free(&q);
	    }
	    else {		/* cats ranges */

		/* set the quant rules for reading the map */
		Rast_set_quant_rules(fd[nfiles], &labels[nfiles].q);
		Rast_quant_get_limits(&labels[nfiles].q, &dmin, &dmax, &min,
				   &max);
	    }
	}
	else {
	    if (Rast_read_range(name, "", &range) < 0)
		G_fatal_error(_("Unable to read range for map <%s>"), name);
	    Rast_get_range_min_max(&range, &min, &max);
	}
	if (!null_set) {
	    null_set = 1;
	    NULL_CELL = max + 1;
	}
	else if (NULL_CELL < max + 1)
	    NULL_CELL = max + 1;

	nfiles++;
    }

    if (dp < 0)
	strcpy(fmt, "%lf");
    else
	sprintf(fmt, "%%.%dlf", dp);

    if (raw_data)
	raw_stats(fd, with_coordinates, with_xy, with_labels);
    else
	cell_stats(fd, with_percents, with_counts, with_areas, with_labels,
		   fmt);

    exit(EXIT_SUCCESS);
}
Example #9
0
int main(int argc, char *argv[])
{
    char rname[GNAME_MAX];	/* Reclassed map name */
    char rmapset[GMAPSET_MAX];	/* Reclassed mapset   */
    const char *mapset;		/* Raster mapset      */
    struct Cell_head cellhd;
    struct GModule *module;
    struct Option *raster, *title_opt, *history_opt;
    struct Option *datasrc1_opt, *datasrc2_opt, *datadesc_opt;
    struct Option *map_opt, *units_opt, *vdatum_opt;
    struct Option *load_opt, *save_opt;
    struct Flag *stats_flag, *null_flag, *del_flag;
    int is_reclass;		/* Is raster reclass? */
    const char *infile;
    char title[MAX_TITLE_LEN + 1];
    struct History hist;

    /* Initialize GIS engine */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("metadata"));
    module->description = _("Allows creation and/or modification of "
			    "raster map layer support files.");

    raster = G_define_standard_option(G_OPT_R_MAP);

    title_opt = G_define_option();
    title_opt->key = "title";
    title_opt->key_desc = "phrase";
    title_opt->type = TYPE_STRING;
    title_opt->required = NO;
    title_opt->description = _("Title for resultant raster map");

    history_opt = G_define_option();
    history_opt->key = "history";
    history_opt->key_desc = "phrase";
    history_opt->type = TYPE_STRING;
    history_opt->required = NO;
    history_opt->description =
	_("Text to append to the next line of the map's metadata file");

    units_opt = G_define_option();
    units_opt->key = "units";
    units_opt->type = TYPE_STRING;
    units_opt->required = NO;
    units_opt->description = _("Text to use for map data units");

    vdatum_opt = G_define_option();
    vdatum_opt->key = "vdatum";
    vdatum_opt->type = TYPE_STRING;
    vdatum_opt->required = NO;
    vdatum_opt->description = _("Text to use for map vertical datum");

    datasrc1_opt = G_define_option();
    datasrc1_opt->key = "source1";
    datasrc1_opt->key_desc = "phrase";
    datasrc1_opt->type = TYPE_STRING;
    datasrc1_opt->required = NO;
    datasrc1_opt->description = _("Text to use for data source, line 1");

    datasrc2_opt = G_define_option();
    datasrc2_opt->key = "source2";
    datasrc2_opt->key_desc = "phrase";
    datasrc2_opt->type = TYPE_STRING;
    datasrc2_opt->required = NO;
    datasrc2_opt->description = _("Text to use for data source, line 2");

    datadesc_opt = G_define_option();
    datadesc_opt->key = "description";
    datadesc_opt->key_desc = "phrase";
    datadesc_opt->type = TYPE_STRING;
    datadesc_opt->required = NO;
    datadesc_opt->description =
	_("Text to use for data description or keyword(s)");

    map_opt = G_define_option();
    map_opt->key = "raster";
    map_opt->type = TYPE_STRING;
    map_opt->required = NO;
    map_opt->gisprompt = "old,cell,raster";
    map_opt->description = _("Raster map from which to copy category table");

    load_opt = G_define_standard_option(G_OPT_F_INPUT);
    load_opt->key = "loadhistory";
    load_opt->required = NO;
    load_opt->description = _("Text file from which to load history");

    save_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    save_opt->key = "savehistory";
    save_opt->required = NO;
    save_opt->description = _("Text file in which to save history");

    stats_flag = G_define_flag();
    stats_flag->key = 's';
    stats_flag->description = _("Update statistics (histogram, range)");

    null_flag = G_define_flag();
    null_flag->key = 'n';
    null_flag->description = _("Create/reset the null file");

    del_flag = G_define_flag();
    del_flag->key = 'd';
    del_flag->description = _("Delete the null file");

    /* Parse command-line options */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* Make sure raster exists and set mapset */
    infile = raster->answer;
    mapset = G_find_raster2(infile, G_mapset());	/* current mapset only for editing */
    if (!mapset || strcmp(mapset, G_mapset()) != 0)
	G_fatal_error(_("Raster map <%s> not found in current mapset"), infile);

    Rast_get_cellhd(raster->answer, "", &cellhd);
    is_reclass = (Rast_is_reclass(raster->answer, "", rname, rmapset) > 0);

    if (title_opt->answer) {
	strncpy(title, title_opt->answer, MAX_TITLE_LEN);
	title[MAX_TITLE_LEN - 1] = '\0';	/* strncpy doesn't null terminate oversized input */
	G_strip(title);
	G_debug(3, "map title= [%s]  (%li chars)", title, strlen(title));
	Rast_read_history(raster->answer, "", &hist);
	Rast_set_history(&hist, HIST_TITLE, title);
	Rast_write_history(raster->answer, &hist);
    }

    if (save_opt->answer) {
	FILE *fp = fopen(save_opt->answer, "w");
	int i;

	if (!fp)
	    G_fatal_error(_("Unable to open output file <%s>"), save_opt->answer);

	Rast_read_history(raster->answer, "", &hist);

	for (i = 0; i < Rast_history_length(&hist); i++)
	    fprintf(fp, "%s\n", Rast_history_line(&hist, i));

	fclose(fp);
    }

    if (load_opt->answer) {
	FILE *fp = fopen(load_opt->answer, "r");

	if (!fp)
	    G_fatal_error(_("Unable to open input file <%s>"), load_opt->answer);

	Rast_read_history(raster->answer, "", &hist);

	Rast_clear_history(&hist);

	for (;;) {
	    char buf[80];
	    if (!G_getl2(buf, sizeof(buf), fp))
		break;
	    Rast_append_history(&hist, buf);
	}

	fclose(fp);

	Rast_write_history(raster->answer, &hist);
    }

    if (history_opt->answer) {
	Rast_read_history(raster->answer, "", &hist);

	/* two less than defined as if only one less a newline gets appended in the hist file. bug? */
	/* Should be RECORD_LEN, but r.info truncates at > 71 chars */
	if (strlen(history_opt->answer) > 71) {
	    int i;

	    for (i = 0; i < strlen(history_opt->answer); i += 71) {
		char buf[72];

		strncpy(buf, &history_opt->answer[i], sizeof(buf)-1);
		buf[sizeof(buf)-1] = '\0';

		Rast_append_history(&hist, buf);
	    }
	}
	else
	    Rast_append_history(&hist, history_opt->answer);

	Rast_write_history(raster->answer, &hist);
    }

    if (units_opt->answer)
	Rast_write_units(raster->answer, units_opt->answer);

    if (vdatum_opt->answer)
	Rast_write_vdatum(raster->answer, vdatum_opt->answer);

    if (datasrc1_opt->answer || datasrc2_opt->answer || datadesc_opt->answer) {
	Rast_read_history(raster->answer, "", &hist);

	if (datasrc1_opt->answer)
	    Rast_set_history(&hist, HIST_DATSRC_1, datasrc1_opt->answer);

	if (datasrc2_opt->answer)
	    Rast_set_history(&hist, HIST_DATSRC_2, datasrc2_opt->answer);

	if (datadesc_opt->answer)
	    Rast_set_history(&hist, HIST_KEYWRD, datadesc_opt->answer);

	Rast_write_history(raster->answer, &hist);
    }

    if (map_opt->answer) {	/* use cats from another map */
	int fd;
	struct Categories cats;

	fd = Rast_open_old(infile, "");
	Rast_init_cats("", &cats);
	if (Rast_read_cats(map_opt->answer, "", &cats) < 0)
	    G_fatal_error(_("Unable to read category file of raster map <%s>"),
			  map_opt->answer);

	Rast_write_cats(infile, &cats);
	G_message(_("cats table for [%s] set to %s"),
		  infile, map_opt->answer);
	Rast_close(fd);
	Rast_free_cats(&cats);
    }


    if (title_opt->answer || history_opt->answer || units_opt->answer
	|| vdatum_opt->answer || datasrc1_opt->answer || datasrc2_opt->answer
	|| datadesc_opt->answer || map_opt->answer)
	exit(EXIT_SUCCESS);


    /* Check the histogram and range */
    if (stats_flag->answer)
	check_stats(raster->answer);

    /* null file */
    if (null_flag->answer) {
	unsigned char *null_bits;
	int row, col;
	int fd;

	if (is_reclass)
	    G_fatal_error(_("[%s] is a reclass of another map. Exiting."),
			  raster->answer);

	/* Create a file of no-nulls */
	null_bits = Rast__allocate_null_bits(cellhd.cols);
	for (col = 0; col < Rast__null_bitstream_size(cellhd.cols); col++)
	    null_bits[col] = 0;

	/* Open null file for writing */
	Rast_set_window(&cellhd);
	fd = Rast__open_null_write(raster->answer);

	G_message(_("Writing new null file for [%s]... "), raster->answer);
	for (row = 0; row < cellhd.rows; row++) {
	    G_percent(row, cellhd.rows, 1);
	    Rast__write_null_bits(fd, null_bits);
	}
	G_percent(row, cellhd.rows, 1);

	/* Cleanup */
	Rast__close_null(fd);
	G_free(null_bits);
    }

    if (del_flag->answer) {
	char path[GPATH_MAX];

	if (is_reclass)
	    G_fatal_error(_("[%s] is a reclass of another map. Exiting."),
			  raster->answer);

	/* Write a file of no-nulls */
	G_message(_("Removing null file for [%s]...\n"), raster->answer);

	G_file_name_misc(path, "cell_misc", "null", raster->answer, G_mapset());
	unlink(path);
	G_file_name_misc(path, "cell_misc", "null2", raster->answer, G_mapset());
	unlink(path);

	G_done_msg(_("Done."));
    }

    return EXIT_SUCCESS;
}
Example #10
0
int main(int argc, char **argv)
{
    char *map_name;
    int maptype;
    int color;
    int i;
    int thin, lines, steps;
    int fp;
    int label_indent;
    int hide_catnum, hide_catstr, show_ticks, show_bg, hide_nodata, do_smooth;
    struct Categories cats;
    struct Colors colors;
    struct GModule *module;
    struct Option *opt_rast2d, *opt_rast3d, *opt_color, *opt_lines,
        *opt_thin, *opt_labelnum, *opt_at, *opt_use, *opt_range,
        *opt_font, *opt_path, *opt_charset, *opt_fontsize, *opt_title,
        *opt_ticks, *opt_tstep, *opt_brdcolor, *opt_bgcolor,
        *opt_tit_fontsize, *opt_digits, *opt_units;
    struct Flag *hidestr, *hidenum, *hidenodata, *smooth, *flipit, *histo,
        *showtick, *showbg, *log_sc;
    double X0, X1, Y0, Y1;
    int flip, UserRange;
    double UserRangeMin, UserRangeMax, UserRangeTemp;
    double *catlist;
    int catlistCount, use_catlist, ticksCount;
    double fontsize;
    char *title;
    char *units;
    double *tick_values;
    double t_step;
    int colorb, colorbg;
    double tit_fontsize;
    int log_scale, digits;

    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("cartography"));
    G_add_keyword(_("legend"));
    module->description =
        _("Displays a legend for a 2D or 3D raster map in the active frame "
          "of the graphics monitor.");

    opt_rast2d = G_define_standard_option(G_OPT_R_MAP);
    opt_rast2d->key = "raster";
    opt_rast2d->required = NO;
    opt_rast2d->guisection = _("Input");

    opt_rast3d = G_define_standard_option(G_OPT_R3_MAP);
    opt_rast3d->key = "raster_3d";
    opt_rast3d->required = NO;
    opt_rast3d->guisection = _("Input");

    opt_title = G_define_option();
    opt_title->key = "title";
    opt_title->type = TYPE_STRING;
    opt_title->required = NO;
    opt_title->description = _("Legend title");
    opt_title->guisection = _("Title");

    opt_tit_fontsize = G_define_option();
    opt_tit_fontsize->key = "title_fontsize";
    opt_tit_fontsize->type = TYPE_DOUBLE;
    opt_tit_fontsize->required = NO;
    opt_tit_fontsize->options = "1-360";
    opt_tit_fontsize->label = _("Title font size");
    opt_tit_fontsize->description = _("Default: Same as fontsize");
    opt_tit_fontsize->guisection = _("Title");

    opt_lines = G_define_option();
    opt_lines->key = "lines";
    opt_lines->type = TYPE_INTEGER;
    opt_lines->answer = "0";
    opt_lines->options = "0-1000";
    opt_lines->description =
        _("Number of text lines (useful for truncating long legends)");
    opt_lines->guisection = _("Advanced");

    opt_thin = G_define_option();
    opt_thin->key = "thin";
    opt_thin->type = TYPE_INTEGER;
    opt_thin->required = NO;
    opt_thin->answer = "1";
    opt_thin->options = "1-1000";
    opt_thin->description =
        _("Thinning factor (thin=10 gives cats 0,10,20...)");
    opt_thin->guisection = _("Advanced");

    opt_units = G_define_option();
    opt_units->key = "units";
    opt_units->type = TYPE_STRING;
    opt_units->required = NO;
    opt_units->description =
            _("Units to display after labels (e.g. meters)");
    opt_units->guisection = _("Advanced");

    opt_labelnum = G_define_option();
    opt_labelnum->key = "labelnum";
    opt_labelnum->type = TYPE_INTEGER;
    opt_labelnum->answer = "5";
    opt_labelnum->options = "2-100";
    opt_labelnum->description =
        _("Number of text labels for smooth gradient legend");
    opt_labelnum->guisection = _("Gradient");

    opt_ticks = G_define_option();
    opt_ticks->key = "label_values";
    opt_ticks->type = TYPE_DOUBLE;
    opt_ticks->required = NO;
    opt_ticks->description = _("Specific values to draw ticks");
    opt_ticks->required = NO;
    opt_ticks->multiple = YES;
    opt_ticks->guisection = _("Gradient");

    opt_tstep = G_define_option();
    opt_tstep->key = "label_step";
    opt_tstep->type = TYPE_DOUBLE;
    opt_tstep->required = NO;
    opt_tstep->description = _("Display label every step");
    opt_tstep->guisection = _("Gradient");

    opt_digits = G_define_option();
    opt_digits->key = "digits";
    opt_digits->type = TYPE_INTEGER;
    opt_digits->required = NO;
    opt_digits->description = _("Number of digits after decimal point");
    opt_digits->guisection = _("Advanced");
    opt_digits->answer = NULL;
    opt_digits->options = "0-6";

    opt_at = G_define_option();
    opt_at->key = "at";
    opt_at->key_desc = "bottom,top,left,right";
    opt_at->type = TYPE_DOUBLE; /* needs to be TYPE_DOUBLE to get past options check */
    opt_at->required = NO;
    opt_at->options = "0-100";
    opt_at->label =
        _("Size and placement as percentage of screen coordinates "
          "(0,0 is lower left)");
    opt_at->description = opt_at->key_desc;
    opt_at->answer = NULL;

    opt_use = G_define_option();
    opt_use->key = "use";
    opt_use->type = TYPE_DOUBLE;        /* string as it is fed through the parser? */
    opt_use->required = NO;
    opt_use->description =
        _("List of discrete category numbers/values for legend");
    opt_use->multiple = YES;
    opt_use->guisection = _("Subset");

    opt_range = G_define_option();
    opt_range->key = "range";
    opt_range->key_desc = "min,max";
    opt_range->type = TYPE_DOUBLE;      /* should it be type_double or _string ?? */
    opt_range->required = NO;
    opt_range->description =
        _("Use a subset of the map range for the legend (min,max)");
    opt_range->guisection = _("Subset");

    opt_color = G_define_standard_option(G_OPT_C);
    opt_color->label = _("Text color");
    opt_color->guisection = _("Font settings");

    opt_font = G_define_option();
    opt_font->key = "font";
    opt_font->type = TYPE_STRING;
    opt_font->required = NO;
    opt_font->description = _("Font name");
    opt_font->guisection = _("Font settings");

    opt_fontsize = G_define_option();
    opt_fontsize->key = "fontsize";
    opt_fontsize->type = TYPE_DOUBLE;
    opt_fontsize->required = NO;
    opt_fontsize->options = "1-360";
    opt_fontsize->label = _("Font size");
    opt_fontsize->description = _("Default: Auto-scaled");
    opt_fontsize->guisection = _("Font settings");

    opt_path = G_define_standard_option(G_OPT_F_INPUT);
    opt_path->key = "path";
    opt_path->required = NO;
    opt_path->description = _("Path to font file");
    opt_path->gisprompt = "old_file,font,file";
    opt_path->guisection = _("Font settings");

    opt_charset = G_define_option();
    opt_charset->key = "charset";
    opt_charset->type = TYPE_STRING;
    opt_charset->required = NO;
    opt_charset->description =
        _("Text encoding (only applicable to TrueType fonts)");
    opt_charset->guisection = _("Font settings");

    opt_brdcolor = G_define_standard_option(G_OPT_CN);
    opt_brdcolor->key = "border_color";
    opt_brdcolor->answer = "black";
    opt_brdcolor->label = _("Border color");
    opt_brdcolor->guisection = _("Background");

    opt_bgcolor = G_define_standard_option(G_OPT_CN);
    opt_bgcolor->key = "bgcolor";
    opt_bgcolor->answer = "white";
    opt_bgcolor->label = _("Background color");
    opt_bgcolor->guisection = _("Background");


    hidestr = G_define_flag();
    hidestr->key = 'v';
    hidestr->description = _("Do not show category labels");
    hidestr->guisection = _("Advanced");

    hidenum = G_define_flag();
    hidenum->key = 'c';
    hidenum->description = _("Do not show category numbers");
    hidenum->guisection = _("Advanced");

    showtick = G_define_flag();
    showtick->key = 't';
    showtick->description = _("Draw legend ticks for labels");
    showtick->guisection = _("Gradient");

    hidenodata = G_define_flag();
    hidenodata->key = 'n';
    hidenodata->description = _("Skip categories with no label");
    hidenodata->guisection = _("Advanced");

    smooth = G_define_flag();
    smooth->key = 's';
    smooth->description = _("Draw smooth gradient");
    smooth->guisection = _("Gradient");

    flipit = G_define_flag();
    flipit->key = 'f';
    flipit->description = _("Flip legend");
    flipit->guisection = _("Advanced");

    histo = G_define_flag();
    histo->key = 'd';
    histo->description = _("Add histogram to smoothed legend");
    histo->guisection = _("Gradient");

    showbg = G_define_flag();
    showbg->key = 'b';
    showbg->description = _("Show background");
    showbg->guisection = _("Background");

    log_sc = G_define_flag();
    log_sc->key = 'l';
    log_sc->description = _("Use logarithmic scale");
    log_sc->guisection = _("Advanced");

    G_option_required(opt_rast2d, opt_rast3d, NULL);
    G_option_exclusive(opt_rast2d, opt_rast3d, NULL);
    G_option_exclusive(hidenum, opt_ticks, NULL);
    G_option_exclusive(hidenum, opt_tstep, NULL);

    /* Check command line */
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    if (opt_rast2d->answer) {
        map_name = opt_rast2d->answer;
        maptype = MAP_TYPE_RASTER2D;
    }
    else {
        map_name = opt_rast3d->answer;
        maptype = MAP_TYPE_RASTER3D;
    }

    if (opt_title->answer)
        title = opt_title->answer;
    else
        title = "";

    if (opt_units->answer) {
        units = opt_units->answer;
    }
    else
        units = "";

    hide_catstr = hidestr->answer;      /* note hide_catstr gets changed and re-read below */
    hide_catnum = hidenum->answer;
    show_ticks = showtick->answer;
    hide_nodata = hidenodata->answer;
    do_smooth = smooth->answer;
    flip = flipit->answer;
    show_bg = showbg->answer;
    log_scale = log_sc->answer;

    if (showtick->answer) {
        label_indent = 12;
    }
    else
        label_indent = 6;

    if (opt_digits->answer != NULL)
        sscanf(opt_digits->answer, "%d", &digits);
    else
        digits = -1;

    color = D_parse_color(opt_color->answer, TRUE);

    if (opt_lines->answer != NULL)
        sscanf(opt_lines->answer, "%d", &lines);

    thin = 1;
    if (opt_thin->answer != NULL)
        sscanf(opt_thin->answer, "%d", &thin);
    if (!thin)
        thin = 1;

    if (opt_labelnum->answer != NULL)
        sscanf(opt_labelnum->answer, "%d", &steps);

    if ((opt_tstep->answer) || (opt_ticks->answer))
        steps = 0;

    if (opt_tstep->answer != NULL)
        t_step = atof(opt_tstep->answer);

    ticksCount = 0;
    if (opt_ticks->answer != NULL) {
        tick_values = (double *)G_calloc(100 + 1, sizeof(double));
        for (i = 0; i < 100; i++)       /* fill with dummy values */
            tick_values[i] = 1.0 * (i + 1);
        tick_values[i] = 0;

        for (i = 0; (opt_ticks->answers[i] != NULL) && i < 100; i++)
            tick_values[i] = atof(opt_ticks->answers[i]);
        ticksCount = i;
    }

    catlistCount = 0;
    if (opt_use->answer != NULL) {      /* should this be answerS ? */
        use_catlist = TRUE;

        catlist = (double *)G_calloc(100 + 1, sizeof(double));
        for (i = 0; i < 100; i++)       /* fill with dummy values */
            catlist[i] = 1.0 * (i + 1);
        catlist[i] = 0;

        for (i = 0; (opt_use->answers[i] != NULL) && i < 100; i++)
            catlist[i] = atof(opt_use->answers[i]);

        catlistCount = i;
    }
    else
        use_catlist = FALSE;


    UserRange = FALSE;
    if (opt_range->answer != NULL) {    /* should this be answerS ? */
        sscanf(opt_range->answers[0], "%lf", &UserRangeMin);
        sscanf(opt_range->answers[1], "%lf", &UserRangeMax);
        UserRange = TRUE;
        if (UserRangeMin > UserRangeMax) {
            UserRangeTemp = UserRangeMax;
            UserRangeMax = UserRangeMin;
            UserRangeMin = UserRangeTemp;
            flip = !flip;
        }
    }

    if (maptype == MAP_TYPE_RASTER2D) {
        if (Rast_read_colors(map_name, "", &colors) == -1)
            G_fatal_error(_("Color file for <%s> not available"), map_name);

        fp = Rast_map_is_fp(map_name, "");

        Rast_read_cats(map_name, "", &cats);
    }
    else {
        if (Rast3d_read_colors(map_name, "", &colors) == -1)
            G_fatal_error(_("Color file for <%s> not available"), map_name);

        fp = TRUE;              /* currently raster 3D is always floating point */

        Rast3d_read_cats(map_name, "", &cats);
    }

    if (fp && !use_catlist) {
        do_smooth = TRUE;
        /* fprintf(stderr, "FP map found - switching gradient legend on\n"); */
        flip = !flip;
    }

    D_open_driver();

    /* Parse and select background color */
    colorb = D_parse_color(opt_brdcolor->answer, TRUE);
    colorbg = D_parse_color(opt_bgcolor->answer, TRUE);

    if (opt_font->answer)
        D_font(opt_font->answer);
    else if (opt_path->answer)
        D_font(opt_path->answer);

    if (opt_fontsize->answer != NULL)
        fontsize = atof(opt_fontsize->answer);
    else
        fontsize = 12;          /* dummy placeholder, should never be called */

    if (opt_charset->answer)
        D_encoding(opt_charset->answer);

    if (opt_tit_fontsize->answer != NULL)
        tit_fontsize = atof(opt_tit_fontsize->answer);
    else
        tit_fontsize = 0;

    if (opt_at->answer != NULL) {
        sscanf(opt_at->answers[0], "%lf", &Y1);
        sscanf(opt_at->answers[1], "%lf", &Y0);
        sscanf(opt_at->answers[2], "%lf", &X0);
        sscanf(opt_at->answers[3], "%lf", &X1);
    }
    else {                      /* default */
        Y1 = 12;
        Y0 = 88;
        X0 = 3;
        X1 = 7;

        if (histo->answer) {
            X0 += 5;
            X1 += 5;
        }
    }

    if (show_bg)
        draw(map_name, maptype, color, thin, lines, steps, fp, label_indent,
             hide_catnum, hide_catstr, show_ticks, hide_nodata, do_smooth,
             cats, colors, X0, X1, Y0, Y1, flip, UserRange, UserRangeMin,
             UserRangeMax, catlist, catlistCount, use_catlist, ticksCount,
             fontsize, tit_fontsize, title, tick_values, t_step, colorb,
             colorbg, opt_use, opt_at, opt_fontsize, opt_tstep,
             opt_range, histo, hidestr, log_scale, 0, digits, units);

    draw(map_name, maptype, color, thin, lines, steps, fp, label_indent,
         hide_catnum, hide_catstr, show_ticks, hide_nodata, do_smooth, cats,
         colors, X0, X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax,
         catlist, catlistCount, use_catlist, ticksCount, fontsize,
         tit_fontsize, title, tick_values, t_step, colorb, colorbg, opt_use,
         opt_at, opt_fontsize, opt_tstep, opt_range, histo,
         hidestr, log_scale, 1, digits, units);

    D_close_driver();

    exit(EXIT_SUCCESS);
}
Example #11
0
File: Gs3.c Project: caomw/grass
/*!
   \brief Get categories/labels

   Formats label as in d.what.rast -> (catval) catlabel 

   \param filename raster map name
   \param drow
   \param dcol
   \param catstr category string

   \return 1 on success
   \return 0 on failure
 */
int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
{
    struct Categories cats;
    const char *mapset;
    CELL *buf;
    DCELL *dbuf;
    RASTER_MAP_TYPE map_type;
    int fd = -1;

    if ((mapset = G_find_raster2(filename, "")) == NULL) {
	G_warning(_("Raster map <%s> not found"), filename);
	return 0;
    }

    if (-1 != Rast_read_cats(filename, mapset, &cats)) {
	fd = Rast_open_old(filename, mapset);
	map_type = Rast_get_map_type(fd);

	if (map_type == CELL_TYPE) {
	    buf = Rast_allocate_c_buf();

	    Rast_get_c_row(fd, buf, drow);
	    if (Rast_is_c_null_value(&buf[dcol])) {
		sprintf(catstr, "(NULL) %s",
			Rast_get_c_cat(&buf[dcol], &cats));
	    }
	    else {
		sprintf(catstr, "(%d) %s", buf[dcol],
			Rast_get_c_cat(&buf[dcol], &cats));
	    }

	    G_free(buf);
	}

	else {
	    /* fp map */
	    dbuf = Rast_allocate_d_buf();

	    Rast_get_d_row(fd, dbuf, drow);
	    if (Rast_is_d_null_value(&dbuf[dcol])) {
		sprintf(catstr, "(NULL) %s",
			Rast_get_d_cat(&dbuf[dcol], &cats));
	    }
	    else {
		sprintf(catstr, "(%g) %s", dbuf[dcol],
			Rast_get_d_cat(&dbuf[dcol], &cats));
	    }

	    G_free(dbuf);
	}
    }
    else {
	strcpy(catstr, "no category label");
	return 0;
    }

    /* TODO: may want to keep these around for multiple queries */
    Rast_free_cats(&cats);

    if (fd >= 0)
	Rast_close(fd);

    return (1);
}
Example #12
0
int make_support(struct rr_state *theState, int percent, double percentage)
{
    char title[100];
    struct History hist;
    struct Categories cats;
    struct Colors clr;
    char *inraster;
    struct RASTER_MAP_PTR nulls;

    /* write categories for output raster 
       use values from input or cover map
     */
    if (theState->docover == 1) {
	inraster = theState->inrcover;
	nulls = theState->cnulls;
    }
    else {
	inraster = theState->inraster;
	nulls = theState->nulls;
    }
    if (Rast_read_cats(inraster, "", &cats) >= 0) {
	sprintf(title, "Random points on <%s>", inraster);
	Rast_set_cats_title(title, &cats);
	if (theState->use_nulls)
	    Rast_set_cat(nulls.data.v,
			     nulls.data.v,
			     "Points with NULL values in original",
			     &cats, nulls.type);
	Rast_write_cats(theState->outraster, &cats);
    }

    /* write history for output raster */
    if (Rast_read_history(theState->outraster, G_mapset(), &hist) >= 0) {
	Rast_short_history(theState->outraster, "raster", &hist);
	Rast_format_history(&hist, HIST_DATSRC_1, "Based on map <%s>", inraster);
	if (percent)
	    Rast_format_history(
		&hist, HIST_DATSRC_2,
		"Random points over %.2f percent of the base map <%s>",
		percentage, inraster);
	else
	    Rast_format_history(
		&hist, HIST_DATSRC_2,
		"%ld random points on the base map <%s>",
		theState->nRand, theState->inraster);

	Rast_command_history(&hist);
	Rast_write_history(theState->outraster, &hist);
    }

    /* write commandline to output vector */
    if (theState->outvector) {
	struct Map_info map;

	Vect_open_old(&map, theState->outvector, G_mapset());
	Vect_hist_command(&map);
	Vect_close(&map);
    }

    /* set colors for output raster */
    if (Rast_read_colors(inraster, "", &clr) >= 0) {
	if (theState->use_nulls) {
	    Rast_add_color_rule(nulls.data.v, 127, 127, 127,
				nulls.data.v, 127, 127, 127, &clr,
				nulls.type);
	}
	Rast_write_colors(theState->outraster, G_mapset(), &clr);
    }

    return 0;
}
Example #13
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;
}
Example #14
0
int main(int argc, char *argv[])
{
    int fd[NFILES];
    int outfd;
    int i;
    const char *name;
    const char *output;
    const char *mapset;
    int non_zero;
    struct Range range;
    CELL ncats, max_cats;
    int primary;
    struct Categories pcats;
    struct Colors pcolr;
    char buf[1024];
    CELL result;
    struct GModule *module;
    struct
    {
	struct Option *input, *output;
    } parm;
    struct
    {
	struct Flag *z;
    } flag;

    G_gisinit(argv[0]);

    /* Define the different options */

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("statistics"));
    module->description =
	_("Creates a cross product of the category values from "
	  "multiple raster map layers.");

    parm.input = G_define_option();
    parm.input->key = "input";
    parm.input->type = TYPE_STRING;
    parm.input->required = YES;
    parm.input->multiple = YES;
    parm.input->gisprompt = "old,cell,raster";
    sprintf(buf, _("Names of 2-%d input raster maps"), NFILES);
    parm.input->description = G_store(buf);

    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);

    /* Define the different flags */

    flag.z = G_define_flag();
    flag.z->key = 'z';
    flag.z->description = _("Non-zero data only");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    nfiles = 0;
    non_zero = flag.z->answer;

    for (nfiles = 0; (name = parm.input->answers[nfiles]); nfiles++) {
	if (nfiles >= NFILES)
	    G_fatal_error(_("More than %d files not allowed"), NFILES);
	mapset = G_find_raster2(name, "");
	if (!mapset)
	    G_fatal_error(_("Raster map <%s> not found"), name);
	names[nfiles] = name;
	fd[nfiles] = Rast_open_old(name, mapset);
	Rast_read_range(name, mapset, &range);
	ncats = range.max - range.min;

	if (nfiles == 0 || ncats > max_cats) {
	    primary = nfiles;
	    max_cats = ncats;
	}
    }

    if (nfiles <= 1)
	G_fatal_error(_("Must specify 2 or more input maps"));
    output = parm.output->answer;
    outfd = Rast_open_c_new(output);

    sprintf(buf, "Cross of %s", names[0]);
    for (i = 1; i < nfiles - 1; i++) {
	strcat(buf, ", ");
	strcat(buf, names[i]);
    }
    strcat(buf, " and ");
    strcat(buf, names[i]);
    Rast_init_cats(buf, &pcats);

    /* first step is cross product, but un-ordered */
    result = cross(fd, non_zero, primary, outfd);

    /* print message STEP mesage */
    G_message(_("%s: STEP 2 ..."), G_program_name());

    /* now close all files */
    for (i = 0; i < nfiles; i++)
	Rast_close(fd[i]);
    Rast_close(outfd);

    if (result <= 0)
	exit(0);


    /* build the renumbering/reclass and the new cats file */
    qsort(reclass, result + 1, sizeof(RECLASS), cmp);
    table = (CELL *) G_calloc(result + 1, sizeof(CELL));
    for (i = 0; i < nfiles; i++) {
	mapset = G_find_raster2(names[i], "");
	Rast_read_cats(names[i], mapset, &labels[i]);
    }

    for (ncats = 0; ncats <= result; ncats++) {
	table[reclass[ncats].result] = ncats;
	set_cat(ncats, reclass[ncats].cat, &pcats);
    }

    for (i = 0; i < nfiles; i++)
	Rast_free_cats(&labels[i]);

    /* reopen the output cell for reading and for writing */
    fd[0] = Rast_open_old(output, G_mapset());
    outfd = Rast_open_c_new(output);

    renumber(fd[0], outfd);

    G_message(_("Creating support files for <%s>..."), output);
    Rast_close(fd[0]);
    Rast_close(outfd);
    Rast_write_cats(output, &pcats);
    Rast_free_cats(&pcats);
    if (result > 0) {
	Rast_make_random_colors(&pcolr, (CELL) 1, result);
	Rast_write_colors(output, G_mapset(), &pcolr);
    }

    G_message(_("%ld categories"), (long)result);
    exit(EXIT_SUCCESS);
}
Example #15
0
int exec_rectify(char *extension, char *interp_method, char *angle_map)
{
    char *name;
    char *mapset;
    char *result;
    char *type = "raster";
    int n;
    struct Colors colr;
    struct Categories cats;
    struct History hist;
    int colr_ok, cats_ok;
    long start_time, rectify_time;
    double aver_z;
    int elevfd;
    struct cache *ebuffer;

    G_debug(1, "Open elevation raster: ");

    /* open elevation raster */
    select_target_env();
    G_set_window(&target_window);
    G_debug(1, "target window: rs=%d cs=%d n=%f s=%f w=%f e=%f\n",
	    target_window.rows, target_window.cols, target_window.north,
	    target_window.south, target_window.west, target_window.east);

    elevfd = Rast_open_old(elev_name, elev_mapset);
    if (elevfd < 0) {
	G_fatal_error(_("Could not open elevation raster"));
	return 1;
    }
    ebuffer = readcell(elevfd, seg_mb_elev, 1);
    select_target_env();
    Rast_close(elevfd);

    /* get an average elevation of the control points */
    /* this is used only if target cells have no elevation */
    get_aver_elev(&group.control_points, &aver_z);

    G_message("-----------------------------------------------");

    /* rectify each file */
    for (n = 0; n < group.group_ref.nfiles; n++) {
	if (!ref_list[n])
	    continue;

	name = group.group_ref.file[n].name;
	mapset = group.group_ref.file[n].mapset;
	result =
	    G_malloc(strlen(group.group_ref.file[n].name) + strlen(extension) + 1);
	strcpy(result, group.group_ref.file[n].name);
	strcat(result, extension);

	G_debug(2, "ORTHO RECTIFYING:");
	G_debug(2, "NAME %s", name);
	G_debug(2, "MAPSET %s", mapset);
	G_debug(2, "RESULT %s", result);
	G_debug(2, "select_current_env...");

	select_current_env();

	cats_ok = Rast_read_cats(name, mapset, &cats) >= 0;
	colr_ok = Rast_read_colors(name, mapset, &colr) > 0;

	/* Initialze History */
	if (Rast_read_history(name, mapset, &hist) < 0)
	    Rast_short_history(result, type, &hist);
	G_debug(2, "reading was fine...");

	time(&start_time);

	G_debug(2, "Starting the rectification...");

	if (rectify(name, mapset, ebuffer, aver_z, result, interp_method)) {
	    G_debug(2, "Done. Writing results...");
	    select_target_env();
	    if (cats_ok) {
		Rast_write_cats(result, &cats);
		Rast_free_cats(&cats);
	    }
	    if (colr_ok) {
		Rast_write_colors(result, G_mapset(), &colr);
		Rast_free_colors(&colr);
	    }
	    /* Write out History */
	    Rast_command_history(&hist);
	    Rast_write_history(result, &hist);

	    select_current_env();
	    time(&rectify_time);
	    report(rectify_time - start_time, 1);
	}
	else
	    report((long)0, 0);

	G_free(result);
    }
    
    close(ebuffer->fd);
    release_cache(ebuffer);

    if (angle_map) {
	camera_angle(angle_map);
    }
    
    return 0;
}
Example #16
0
File: main.c Project: caomw/grass
int main(int argc, char **argv)
{
    static DCELL *count, *sum, *mean, *sumu, *sum2, *sum3, *sum4, *min, *max;
    DCELL *result;
    struct GModule *module;
    struct {
	struct Option *method, *basemap, *covermap, *output;
    } opt;
    struct {
	struct Flag *c, *r;
    } flag;
    char methods[2048];
    const char *basemap, *covermap, *output;
    int usecats;
    int reclass;
    int base_fd, cover_fd;
    struct Categories cats;
    CELL *base_buf;
    DCELL *cover_buf;
    struct Range range;
    CELL mincat, ncats;
    int method;
    int rows, cols;
    int row, col, i;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("statistics"));
    module->description =
	_("Calculates category or object oriented statistics (accumulator-based statistics).");

    opt.basemap = G_define_standard_option(G_OPT_R_BASE);

    opt.covermap = G_define_standard_option(G_OPT_R_COVER);

    opt.method = G_define_option();
    opt.method->key = "method";
    opt.method->type = TYPE_STRING;
    opt.method->required = YES;
    opt.method->description = _("Method of object-based statistic");

    for (i = 0; menu[i].name; i++) {
	if (i)
	    strcat(methods, ",");
	else
	    *(methods) = 0;
	strcat(methods, menu[i].name);
    }
    opt.method->options = G_store(methods);

    for (i = 0; menu[i].name; i++) {
	if (i)
	    strcat(methods, ";");
	else
	    *(methods) = 0;
	strcat(methods, menu[i].name);
	strcat(methods, ";");
	strcat(methods, menu[i].text);
    }
    opt.method->descriptions = G_store(methods);

    opt.output = G_define_standard_option(G_OPT_R_OUTPUT);
    opt.output->description = _("Resultant raster map");
    opt.output->required = YES;

    flag.c = G_define_flag();
    flag.c->key = 'c';
    flag.c->description =
	_("Cover values extracted from the category labels of the cover map");

    flag.r = G_define_flag();
    flag.r->key = 'r';
    flag.r->description =
	_("Create reclass map with statistics as category labels");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    basemap = opt.basemap->answer;
    covermap = opt.covermap->answer;
    output = opt.output->answer;
    usecats = flag.c->answer;
    reclass = flag.r->answer;

    for (i = 0; menu[i].name; i++)
	if (strcmp(menu[i].name, opt.method->answer) == 0)
	    break;

    if (!menu[i].name) {
	G_warning(_("<%s=%s> unknown %s"), opt.method->key, opt.method->answer,
		  opt.method->key);
	G_usage();
	exit(EXIT_FAILURE);
    }

    method = menu[i].val;

    base_fd = Rast_open_old(basemap, "");

    cover_fd = Rast_open_old(covermap, "");

    if (usecats && Rast_read_cats(covermap, "", &cats) < 0)
	G_fatal_error(_("Unable to read category file of cover map <%s>"), covermap);

    if (Rast_map_is_fp(basemap, "") != 0)
	G_fatal_error(_("The base map must be an integer (CELL) map"));

    if (Rast_read_range(basemap, "", &range) < 0)
	G_fatal_error(_("Unable to read range of base map <%s>"), basemap);

    mincat = range.min;
    ncats = range.max - range.min + 1;

    rows = Rast_window_rows();
    cols = Rast_window_cols();

    switch (method) {
    case COUNT:
	count = G_calloc(ncats, sizeof(DCELL));
	break;
    case SUM:
	sum = G_calloc(ncats, sizeof(DCELL));
	break;
    case MIN:
	min = G_malloc(ncats * sizeof(DCELL));
	break;
    case MAX:
	max = G_malloc(ncats * sizeof(DCELL));
	break;
    case RANGE:
	min = G_malloc(ncats * sizeof(DCELL));
	max = G_malloc(ncats * sizeof(DCELL));
	break;
    case AVERAGE:
    case ADEV:
    case VARIANCE2:
    case STDDEV2:
    case SKEWNESS2:
    case KURTOSIS2:
	count = G_calloc(ncats, sizeof(DCELL));
	sum = G_calloc(ncats, sizeof(DCELL));
	break;
    case VARIANCE1:
    case STDDEV1:
	count = G_calloc(ncats, sizeof(DCELL));
	sum = G_calloc(ncats, sizeof(DCELL));
	sum2 = G_calloc(ncats, sizeof(DCELL));
	break;
    case SKEWNESS1:
	count = G_calloc(ncats, sizeof(DCELL));
	sum = G_calloc(ncats, sizeof(DCELL));
	sum2 = G_calloc(ncats, sizeof(DCELL));
	sum3 = G_calloc(ncats, sizeof(DCELL));
	break;
    case KURTOSIS1:
	count = G_calloc(ncats, sizeof(DCELL));
	sum = G_calloc(ncats, sizeof(DCELL));
	sum2 = G_calloc(ncats, sizeof(DCELL));
	sum4 = G_calloc(ncats, sizeof(DCELL));
	break;
    }

    if (min)
	for (i = 0; i < ncats; i++)
	    min[i] = 1e300;
    if (max)
	for (i = 0; i < ncats; i++)
	    max[i] = -1e300;

    base_buf = Rast_allocate_c_buf();
    cover_buf = Rast_allocate_d_buf();

    G_message(_("First pass"));

    for (row = 0; row < rows; row++) {
	Rast_get_c_row(base_fd, base_buf, row);
	Rast_get_d_row(cover_fd, cover_buf, row);

	for (col = 0; col < cols; col++) {
	    int n;
	    DCELL v;

	    if (Rast_is_c_null_value(&base_buf[col]))
		continue;
	    if (Rast_is_d_null_value(&cover_buf[col]))
		continue;

	    n = base_buf[col] - mincat;

	    if (n < 0 || n >= ncats)
		continue;

	    v = cover_buf[col];
	    if (usecats)
		sscanf(Rast_get_c_cat((CELL *) &v, &cats), "%lf", &v);

	    if (count)
		count[n]++;
	    if (sum)
		sum[n] += v;
	    if (sum2)
		sum2[n] += v * v;
	    if (sum3)
		sum3[n] += v * v * v;
	    if (sum4)
		sum4[n] += v * v * v * v;
	    if (min && min[n] > v)
		min[n] = v;
	    if (max && max[n] < v)
		max[n] = v;
	}

	G_percent(row, rows, 2);
    }

    G_percent(row, rows, 2);

    result = G_calloc(ncats, sizeof(DCELL));

    switch (method) {
    case ADEV:
    case VARIANCE2:
    case STDDEV2:
    case SKEWNESS2:
    case KURTOSIS2:
	mean = G_calloc(ncats, sizeof(DCELL));
	for (i = 0; i < ncats; i++)
	    mean[i] = sum[i] / count[i];
	G_free(sum);
	break;
    }

    switch (method) {
    case ADEV:
	sumu = G_calloc(ncats, sizeof(DCELL));
	break;
    case VARIANCE2:
    case STDDEV2:
	sum2 = G_calloc(ncats, sizeof(DCELL));
	break;
    case SKEWNESS2:
	sum2 = G_calloc(ncats, sizeof(DCELL));
	sum3 = G_calloc(ncats, sizeof(DCELL));
	break;
    case KURTOSIS2:
	sum2 = G_calloc(ncats, sizeof(DCELL));
	sum4 = G_calloc(ncats, sizeof(DCELL));
	break;
    }

    if (mean) {
	G_message(_("Second pass"));

	for (row = 0; row < rows; row++) {
	    Rast_get_c_row(base_fd, base_buf, row);
	    Rast_get_d_row(cover_fd, cover_buf, row);

	    for (col = 0; col < cols; col++) {
		int n;
		DCELL v, d;

		if (Rast_is_c_null_value(&base_buf[col]))
		    continue;
		if (Rast_is_d_null_value(&cover_buf[col]))
		    continue;

		n = base_buf[col] - mincat;

		if (n < 0 || n >= ncats)
		    continue;

		v = cover_buf[col];
		if (usecats)
		    sscanf(Rast_get_c_cat((CELL *) &v, &cats), "%lf", &v);
		d = v - mean[n];

		if (sumu)
		    sumu[n] += fabs(d);
		if (sum2)
		    sum2[n] += d * d;
		if (sum3)
		    sum3[n] += d * d * d;
		if (sum4)
		    sum4[n] += d * d * d * d;
	    }

	    G_percent(row, rows, 2);
	}

	G_percent(row, rows, 2);
	G_free(mean);
	G_free(cover_buf);
    }

    switch (method) {
    case COUNT:
	for (i = 0; i < ncats; i++)
	    result[i] = count[i];
	break;
    case SUM:
	for (i = 0; i < ncats; i++)
	    result[i] = sum[i];
	break;
    case AVERAGE:
	for (i = 0; i < ncats; i++)
	    result[i] = sum[i] / count[i];
	break;
    case MIN:
	for (i = 0; i < ncats; i++)
	    result[i] = min[i];
	break;
    case MAX:
	for (i = 0; i < ncats; i++)
	    result[i] = max[i];
	break;
    case RANGE:
	for (i = 0; i < ncats; i++)
	    result[i] = max[i] - min[i];
	break;
    case VARIANCE1:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1);
	    result[i] = var;
	}
	break;
    case STDDEV1:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1);
	    result[i] = sqrt(var);
	}
	break;
    case SKEWNESS1:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1);
	    double skew = (sum3[i] / n
			   - 3 * sum[i] * sum2[i] / (n * n)
			   + 2 * sum[i] * sum[i] * sum[i] / (n * n * n))
		/ (pow(var, 1.5));
	    result[i] = skew;
	}
	break;
    case KURTOSIS1:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1);
	    double kurt = (sum4[i] / n
			   - 4 * sum[i] * sum3[i] / (n * n)
			   + 6 * sum[i] * sum[i] * sum2[i] / (n * n * n)
			   - 3 * sum[i] * sum[i] * sum[i] * sum[i] / (n * n * n * n))
		/ (var * var) - 3;
	    result[i] = kurt;
	}
	break;
    case ADEV:
	for (i = 0; i < ncats; i++)
	    result[i] = sumu[i] / count[i];
	break;
    case VARIANCE2:
	for (i = 0; i < ncats; i++)
	    result[i] = sum2[i] / (count[i] - 1);
	break;
    case STDDEV2:
	for (i = 0; i < ncats; i++)
	    result[i] = sqrt(sum2[i] / (count[i] - 1));
	break;
    case SKEWNESS2:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = sum2[i] / (n - 1);
	    double sdev = sqrt(var);
	    result[i] = sum3[i] / (sdev * sdev * sdev) / n;
	}
	G_free(count);
	G_free(sum2);
	G_free(sum3);
	break;
    case KURTOSIS2:
	for (i = 0; i < ncats; i++) {
	    double n = count[i];
	    double var = sum2[i] / (n - 1);
	    result[i] = sum4[i] / (var * var) / n - 3;
	}
	G_free(count);
	G_free(sum2);
	G_free(sum4);
	break;
    }

    if (reclass) {
	const char *tempfile = G_tempfile();
	char *input_arg = G_malloc(strlen(basemap) + 7);
	char *output_arg = G_malloc(strlen(output) + 8);
	char *rules_arg = G_malloc(strlen(tempfile) + 7);
	FILE *fp;

	G_message(_("Generating reclass map"));

	sprintf(input_arg, "input=%s", basemap);
	sprintf(output_arg, "output=%s", output);
	sprintf(rules_arg, "rules=%s", tempfile);

	fp = fopen(tempfile, "w");
	if (!fp)
	    G_fatal_error(_("Unable to open temporary file"));

	for (i = 0; i < ncats; i++)
	    fprintf(fp, "%d = %d %f\n", mincat + i, mincat + i, result[i]);

	fclose(fp);

	G_spawn("r.reclass", "r.reclass", input_arg, output_arg, rules_arg, NULL);
    }
    else {
	int out_fd;
	DCELL *out_buf;
	struct Colors colors;

	G_message(_("Writing output map"));

	out_fd = Rast_open_fp_new(output);

	out_buf = Rast_allocate_d_buf();

	for (row = 0; row < rows; row++) {
	    Rast_get_c_row(base_fd, base_buf, row);

	    for (col = 0; col < cols; col++)
		if (Rast_is_c_null_value(&base_buf[col]))
		    Rast_set_d_null_value(&out_buf[col], 1);
		else
		    out_buf[col] = result[base_buf[col] - mincat];

	    Rast_put_d_row(out_fd, out_buf);

	    G_percent(row, rows, 2);
	}

	G_percent(row, rows, 2);

	Rast_close(out_fd);

	if (Rast_read_colors(covermap, "", &colors) > 0)
	    Rast_write_colors(output, G_mapset(), &colors);
    }

    return 0;
}
Example #17
0
void read_labels(struct Map *map)
{
    if (Rast_read_cats(map->name, map->mapset, &map->labels) < 0)
        exit(1);
}
Example #18
0
/* *************************************************************** */
int main(int argc, char *argv[])
{
    int i, j;
    int nfiles;
    int fd[NFILES];
    struct Categories cats[NFILES];
    struct Cell_head window;
    struct Colors ncolor[NFILES];
    struct Colors colors;
    RASTER_MAP_TYPE out_type[NFILES];
    CELL *cell[NFILES];
    DCELL *dcell[NFILES];

    /*   int row, col; */
    double drow, dcol;
    int row_in_window, in_window;
    double east, north;
    int line;
    char buffer[1024];
    char **ptr;
    struct Option *opt1, *opt2, *opt3, *opt4, *opt_fs;
    struct Flag *label_flag, *cache_flag, *int_flag, *color_flag, *header_flag;
    char fs;
    int Cache_size;
    int done = FALSE;
    int point, point_cnt;
    struct order *cache;
    int cur_row;
    int projection;
    int cache_hit = 0, cache_miss = 0;
    int cache_hit_tot = 0, cache_miss_tot = 0;
    int pass = 0;
    int cache_report = FALSE;
    char tmp_buf[500], *null_str;
    int red, green, blue;
    struct GModule *module;


    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    module->description =
	_("Queries raster map layers on their category values and category labels.");

    opt1 = G_define_option();
    opt1->key = "input";
    opt1->type = TYPE_STRING;
    opt1->required = YES;
    opt1->multiple = YES;
    opt1->gisprompt = "old,cell,raster";
    opt1->description = _("Name of existing raster map(s) to query");

    opt2 = G_define_option();
    opt2->key = "cache";
    opt2->type = TYPE_INTEGER;
    opt2->required = NO;
    opt2->multiple = NO;
    opt2->description = _("Size of point cache");
    opt2->answer = "500";
    opt2->guisection = _("Advanced");

    opt3 = G_define_option();
    opt3->key = "null";
    opt3->type = TYPE_STRING;
    opt3->required = NO;
    opt3->answer = "*";
    opt3->description = _("Char string to represent no data cell");

    opt_fs = G_define_standard_option(G_OPT_F_SEP);

    opt4 = G_define_option();
    opt4->key = "east_north";
    opt4->type = TYPE_DOUBLE;
    opt4->key_desc = "east,north";
    opt4->required = NO;
    opt4->multiple = YES;
    opt4->description = _("Coordinates for query");

    header_flag = G_define_flag();
    header_flag->key = 'n';
    header_flag->description = _("Output header row");

    label_flag = G_define_flag();
    label_flag->key = 'f';
    label_flag->description = _("Show the category labels of the grid cell(s)");

    color_flag = G_define_flag();
    color_flag->key = 'r';
    color_flag->description = _("Output color values as RRR:GGG:BBB");

    int_flag = G_define_flag();
    int_flag->key = 'i';
    int_flag->description = _("Output integer category values, not cell values");

    cache_flag = G_define_flag();
    cache_flag->key = 'c';
    cache_flag->description = _("Turn on cache reporting");
    cache_flag->guisection = _("Advanced");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    tty = isatty(0);

    projection = G_projection();

    /* see v.in.ascii for a better solution */
    if (opt_fs->answer != NULL) {
	if (strcmp(opt_fs->answer, "space") == 0)
	    fs = ' ';
	else if (strcmp(opt_fs->answer, "tab") == 0)
	    fs = '\t';
	else if (strcmp(opt_fs->answer, "\\t") == 0)
	    fs = '\t';
	else
	    fs = opt_fs->answer[0];
    }

    null_str = opt3->answer;


    if (tty)
	Cache_size = 1;
    else
	Cache_size = atoi(opt2->answer);

    if (Cache_size < 1)
	Cache_size = 1;

    cache = (struct order *)G_malloc(sizeof(struct order) * Cache_size);

    /*enable cache report */
    if (cache_flag->answer)
	cache_report = TRUE;


    ptr = opt1->answers;
    nfiles = 0;
    for (; *ptr != NULL; ptr++) {
	char name[GNAME_MAX];

	if (nfiles >= NFILES)
	    G_fatal_error(_("can only do up to %d raster maps"),
			  NFILES);

	strcpy(name, *ptr);
	fd[nfiles] = Rast_open_old(name, "");

	out_type[nfiles] = Rast_get_map_type(fd[nfiles]);
	if (int_flag->answer)
	    out_type[nfiles] = CELL_TYPE;

	if (color_flag->answer) {
	    Rast_read_colors(name, "", &colors);
	    ncolor[nfiles] = colors;
	}

	if (label_flag->answer && Rast_read_cats(name, "", &cats[nfiles]) < 0)
	    G_fatal_error(_("Unable to read category file for <%s>"), name);

	nfiles++;
    }

    for (i = 0; i < nfiles; i++) {
	if (int_flag->answer)
	    out_type[i] = CELL_TYPE;

	cell[i] = Rast_allocate_c_buf();
	if (out_type[i] != CELL_TYPE)
	    dcell[i] = Rast_allocate_d_buf();
    }

    G_get_window(&window);


    if(header_flag->answer) {
	fprintf(stdout, "easting%cnorthing%csite_name", fs, fs);

	ptr = opt1->answers;
	for (; *ptr != NULL; ptr++) {
	    char name[GNAME_MAX];
	    strcpy(name, *ptr);

	    fprintf(stdout, "%c%s", fs, name);

	    if (label_flag->answer)
		fprintf(stdout, "%c%s_label", fs, name);
	    if (color_flag->answer)
		fprintf(stdout, "%c%s_color", fs, name);
	}

	fprintf(stdout, "\n");
    }

    line = 0;
    if (!opt4->answers && tty)
	fprintf(stderr, "enter points, \"end\" to quit\n");

    j = 0;
    done = FALSE;
    while (!done) {
	pass++;
	if (cache_report & !tty)
	    fprintf(stderr, "Pass %3d  Line %6d   - ", pass, line);

	cache_hit = cache_miss = 0;

	if (!opt4->answers && tty) {
	    fprintf(stderr, "\neast north [label] >  ");
	    Cache_size = 1;
	}
	{
	    point_cnt = 0;
	    for (i = 0; i < Cache_size; i++) {
		if (!opt4->answers && fgets(buffer, 1000, stdin) == NULL)
		    done = TRUE;
		else {
		    line++;
		    if ((!opt4->answers &&
			 (strncmp(buffer, "end\n", 4) == 0 ||
			  strncmp(buffer, "exit\n", 5) == 0)) ||
			(opt4->answers && !opt4->answers[j]))
			done = TRUE;
		    else {
			*(cache[point_cnt].lab_buf) =
			    *(cache[point_cnt].east_buf) =
			    *(cache[point_cnt].north_buf) = 0;
			if (!opt4->answers)
			    sscanf(buffer, "%s %s %[^\n]",
				   cache[point_cnt].east_buf,
				   cache[point_cnt].north_buf,
				   cache[point_cnt].lab_buf);
			else {
			    strcpy(cache[point_cnt].east_buf,
				   opt4->answers[j++]);
			    strcpy(cache[point_cnt].north_buf,
				   opt4->answers[j++]);
			}
			if (*(cache[point_cnt].east_buf) == 0)
			    continue;	/* skip blank lines */

			if (*(cache[point_cnt].north_buf) == 0) {
			    oops(line, buffer,
				 "two coordinates (east north) required");
			    continue;
			}
			if (!G_scan_northing
			    (cache[point_cnt].north_buf, &north, window.proj)
			    || !G_scan_easting(cache[point_cnt].east_buf,
					       &east, window.proj)) {
			    oops(line, buffer, "invalid coordinate(s)");
			    continue;
			}

			/* convert north, east to row and col */
			drow = Rast_northing_to_row(north, &window);
			dcol = Rast_easting_to_col(east, &window);

			/* a special case.
			 *   if north falls at southern edge, or east falls on eastern edge,
			 *   the point will appear outside the window.
			 *   So, for these edges, bring the point inside the window
			 */
			if (drow == window.rows)
			    drow--;
			if (dcol == window.cols)
			    dcol--;

			cache[point_cnt].row = (int)drow;
			cache[point_cnt].col = (int)dcol;
			cache[point_cnt].point = point_cnt;
			point_cnt++;
		    }
		}
	    }
	}

	if (Cache_size > 1)
	    qsort(cache, point_cnt, sizeof(struct order), by_row);

	/* extract data from files and store in cache */

	cur_row = -99;

	for (point = 0; point < point_cnt; point++) {
	    row_in_window = 1;
	    in_window = 1;
	    if (cache[point].row < 0 || cache[point].row >= window.rows)
		row_in_window = in_window = 0;
	    if (cache[point].col < 0 || cache[point].col >= window.cols)
		in_window = 0;

	    if (!in_window) {
		if (tty)
		    fprintf(stderr,
			    "** note ** %s %s is outside your current window\n",
			    cache[point].east_buf, cache[point].north_buf);
	    }

	    if (cur_row != cache[point].row) {
		cache_miss++;
		if (row_in_window)
		    for (i = 0; i < nfiles; i++) {
			Rast_get_c_row(fd[i], cell[i], cache[point].row);

			if (out_type[i] != CELL_TYPE)
			    Rast_get_d_row(fd[i], dcell[i], cache[point].row);
		    }

		cur_row = cache[point].row;
	    }
	    else
		cache_hit++;

	    for (i = 0; i < nfiles; i++) {
		if (in_window)
		    cache[point].value[i] = cell[i][cache[point].col];
		else
		    Rast_set_c_null_value(&(cache[point].value[i]), 1);

		if (out_type[i] != CELL_TYPE) {
		    if (in_window)
			cache[point].dvalue[i] = dcell[i][cache[point].col];
		    else
			Rast_set_d_null_value(&(cache[point].dvalue[i]), 1);
		}
		if (color_flag->answer) {
		    if (out_type[i] == CELL_TYPE)
			Rast_get_c_color(&cell[i][cache[point].col],
					     &red, &green, &blue, &ncolor[i]);
		    else
			Rast_get_d_color(&dcell[i][cache[point].col],
					     &red, &green, &blue, &ncolor[i]);

		    sprintf(cache[point].clr_buf[i], "%03d:%03d:%03d", red,
			    green, blue);
		}

	    }
	}			/* point loop */

	if (Cache_size > 1)
	    qsort(cache, point_cnt, sizeof(struct order), by_point);

	/* report data from re-ordered cache */

	for (point = 0; point < point_cnt; point++) {

	    G_debug(1, "%s|%s at col %d, row %d\n",
		    cache[point].east_buf, cache[point].north_buf,
		    cache[point].col, cache[point].row);


	    fprintf(stdout, "%s%c%s%c%s", cache[point].east_buf, fs,
		    cache[point].north_buf, fs, cache[point].lab_buf);

	    for (i = 0; i < nfiles; i++) {
		if (out_type[i] == CELL_TYPE) {
		    if (Rast_is_c_null_value(&cache[point].value[i])) {
			fprintf(stdout, "%c%s", fs, null_str);
			if (label_flag->answer)
			    fprintf(stdout, "%c", fs);
			if (color_flag->answer)
			    fprintf(stdout, "%c", fs);
			continue;
		    }
		    fprintf(stdout, "%c%ld", fs, (long)cache[point].value[i]);
		}
		else {		/* FCELL or DCELL */

		    if (Rast_is_d_null_value(&cache[point].dvalue[i])) {
			fprintf(stdout, "%c%s", fs, null_str);
			if (label_flag->answer)
			    fprintf(stdout, "%c", fs);
			if (color_flag->answer)
			    fprintf(stdout, "%c", fs);
			continue;
		    }
		    if (out_type[i] == FCELL_TYPE)
			sprintf(tmp_buf, "%.7g", cache[point].dvalue[i]);
		    else /* DCELL */
			sprintf(tmp_buf, "%.15g", cache[point].dvalue[i]);
		    G_trim_decimal(tmp_buf); /* not needed with %g? */
		    fprintf(stdout, "%c%s", fs, tmp_buf);
		}
		if (label_flag->answer)
		    fprintf(stdout, "%c%s", fs,
			    Rast_get_c_cat(&(cache[point].value[i]), &cats[i]));
		if (color_flag->answer)
		    fprintf(stdout, "%c%s", fs, cache[point].clr_buf[i]);
	    }
	    fprintf(stdout, "\n");
	}

	if (cache_report & !tty)
	    fprintf(stderr, "Cache  Hit: %6d  Miss: %6d\n",
		    cache_hit, cache_miss);

	cache_hit_tot += cache_hit;
	cache_miss_tot += cache_miss;
	cache_hit = cache_miss = 0;
    }

    if (!opt4->answers && tty)
	fprintf(stderr, "\n");
    if (cache_report & !tty)
	fprintf(stderr, "Total:    Cache  Hit: %6d  Miss: %6d\n",
		cache_hit_tot, cache_miss_tot);

    exit(EXIT_SUCCESS);
}