Пример #1
0
int main(int argc, char **argv)
{
    struct GModule *module;
    struct
    {
	struct Option *text;
	struct Option *size;
	struct Option *fgcolor;
	struct Option *bgcolor;
	struct Option *line;
	struct Option *at;
	struct Option *rotation;
	struct Option *align;
	struct Option *linespacing;
	struct Option *font;
	struct Option *path;
	struct Option *charset;
	struct Option *input;
    } opt;
    struct
    {
	struct Flag *p;
	struct Flag *g;
	struct Flag *b;
	struct Flag *r;
	struct Flag *s;
    } flag;

    /* options and flags */
    char *text;
    double size;
    double x, y;
    int line;
    double rotation;
    char align[3];
    double linespacing;

    char bold;

    /* window info */
    struct rectinfo win;

    /* command file */
    FILE *cmd_fp;

    char buf[512];

    int first_text;
    int linefeed;
    int set_l;
    double orig_x, orig_y;
    double prev_x, prev_y;
    double set_x, set_y;
    double east, north;
    int do_background, fg_color, bg_color;

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

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("cartography"));
    module->description =
	_("Draws text in the active display frame on the graphics monitor using the current font.");

    opt.text = G_define_option();
    opt.text->key = "text";
    opt.text->type = TYPE_STRING;
    opt.text->required = NO;
    opt.text->description = _("Text to display");
    opt.text->guisection = _("Input");

    opt.input = G_define_standard_option(G_OPT_F_INPUT);
    opt.input->required = NO;
    opt.input->description = _("Input file");
    opt.input->guisection = _("Input");

    opt.fgcolor = G_define_option();
    opt.fgcolor->key = "color";
    opt.fgcolor->type = TYPE_STRING;
    opt.fgcolor->answer = DEFAULT_COLOR;
    opt.fgcolor->required = NO;
    opt.fgcolor->description =
	_("Text color, either a standard GRASS color or R:G:B triplet");
    opt.fgcolor->gisprompt = "old_color,color,color";
    opt.fgcolor->guisection = _("Text");

    opt.bgcolor = G_define_option();
    opt.bgcolor->key = "bgcolor";
    opt.bgcolor->type = TYPE_STRING;
    opt.bgcolor->required = NO;
    opt.bgcolor->description =
        _("Text background color, either a standard GRASS color or R:G:B triplet");
    opt.bgcolor->gisprompt = "old_color,color,color";
    opt.bgcolor->guisection = _("Text");

    opt.rotation = G_define_option();
    opt.rotation->key = "rotation";
    opt.rotation->type = TYPE_DOUBLE;
    opt.rotation->required = NO;
    opt.rotation->answer = "0";
    opt.rotation->description =
    _("Rotation angle in degrees (counter-clockwise)");
    opt.rotation->guisection = _("Text");

    opt.linespacing = G_define_option();
    opt.linespacing->key = "linespacing";
    opt.linespacing->type = TYPE_DOUBLE;
    opt.linespacing->required = NO;
    opt.linespacing->answer = "1.25";
    opt.linespacing->description = _("Line spacing");
    opt.linespacing->guisection = _("Text");

    opt.at = G_define_option();
    opt.at->key = "at";
    opt.at->key_desc = "x,y";
    opt.at->type = TYPE_DOUBLE;
    opt.at->required = NO;
    opt.at->description =
	_("Screen position at which text will begin to be drawn (percentage, [0,0] is lower left)");
    opt.at->guisection = _("Position");

    opt.line = G_define_option();
    opt.line->key = "line";
    opt.line->required = NO;
    opt.line->type = TYPE_INTEGER;
    opt.line->options = "1-1000";
    opt.line->description =
	_("The screen line number on which text will begin to be drawn");
    opt.line->guisection = _("Position");

    opt.align = G_define_option();
    opt.align->key = "align";
    opt.align->type = TYPE_STRING;
    opt.align->required = NO;
    opt.align->answer = "ll";
    opt.align->options = "ll,lc,lr,cl,cc,cr,ul,uc,ur";
    opt.align->description = _("Text alignment");
    opt.align->guisection = _("Position");

    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.size = G_define_option();
    opt.size->key = "size";
    opt.size->type = TYPE_DOUBLE;
    opt.size->required = NO;
    opt.size->answer = "5";
    opt.size->options = "0-100";
    opt.size->description =
    _("Height of letters in percentage of available frame height");
    opt.size->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,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");

    flag.p = G_define_flag();
    flag.p->key = 'p';
    flag.p->description = _("Screen position in pixels ([0,0] is top left)");
    flag.p->guisection = _("Position");

    flag.g = G_define_flag();
    flag.g->key = 'g';
    flag.g->description = _("Screen position in geographic coordinates");
    flag.g->guisection = _("Position");

    flag.b = G_define_flag();
    flag.b->key = 'b';
    flag.b->description = _("Use bold text");
    flag.b->guisection = _("Text");

    flag.r = G_define_flag();
    flag.r->key = 'r';
    flag.r->description = _("Use radians instead of degrees for rotation");
    flag.r->guisection = _("Text");

    flag.s = G_define_flag();
    flag.s->key = 's';
    flag.s->description = _("Font size is height in pixels");
    flag.s->guisection = _("Font settings");


    /* check command line */
    if (G_parser(argc, argv))
	exit(1);

    /* parse and check options and flags */

    if ((opt.line->answer && opt.at->answer) ||
	(flag.p->answer && flag.g->answer))
	G_fatal_error(_("Please choose only one placement method"));

    text = opt.text->answer;

    line = (opt.line->answer ? atoi(opt.line->answer) : 1);

    /* calculate rotation angle in radian */
    rotation = atof(opt.rotation->answer);
    if (!flag.r->answer)
	rotation *= M_PI / 180.0;
    rotation = fmod(rotation, 2.0 * M_PI);
    if (rotation < 0.0)
	rotation += 2.0 * M_PI;

    strncpy(align, opt.align->answer, 2);
    linespacing = atof(opt.linespacing->answer);

    bold = flag.b->answer;

    D_open_driver();
    
    if (opt.font->answer)
	D_font(opt.font->answer);
    else if (opt.path->answer)
	D_font(opt.path->answer);

    if (opt.charset->answer)
	D_encoding(opt.charset->answer);

    D_setup_unity(0);

    /* figure out where to put text */
    D_get_src(&win.t, &win.b, &win.l, &win.r);

    if (flag.s->answer)
	size = atof(opt.size->answer);
    else
#ifdef BACKWARD_COMPATIBILITY
	size = atof(opt.size->answer) / 100.0 * (win.b - win.t) / linespacing;
#else
	size = atof(opt.size->answer) / 100.0 * (win.b - win.t);
#endif

    fg_color = D_parse_color(opt.fgcolor->answer, TRUE);
    if (opt.bgcolor->answer) {
	do_background = 1;
	bg_color = D_parse_color(opt.bgcolor->answer, TRUE);
	if (bg_color == 0) /* ie color="none" */
	    do_background = 0;
    } else
	do_background = 0;
    set_color(opt.fgcolor->answer);

    orig_x = orig_y = 0;

    if (opt.at->answer) {
	if (get_coordinates(&x, &y, &east, &north,
			    win, opt.at->answers,
			    flag.p->answer, flag.g->answer))
	    G_fatal_error(_("Invalid coordinates"));
	orig_x = x;
	orig_y = y;
    }
    else {
	x = win.l + (size * linespacing + 0.5) - size;	/* d.text: +5 */
	y = win.t + line * (size * linespacing + 0.5);
    }

    prev_x = x;
    prev_y = y;

    D_text_size(size, size);
    D_text_rotation(rotation * 180.0 / M_PI);

    if (text) {
	double x2, y2;

	x2 = x;
	y2 = y;

	if (text[0])
	    draw_text(text, &x2, &y2, size, align, rotation, bold, do_background, fg_color, bg_color);

	/* reset */
	D_text_size(5, 5);
	D_text_rotation(0.0);

	D_save_command(G_recreate_command());
	D_close_driver();

	exit(EXIT_SUCCESS);
    }

    if (!opt.input->answer || strcmp(opt.input->answer, "-") == 0)
	cmd_fp = stdin;
    else {
	cmd_fp = fopen(opt.input->answer, "r");
	if (!cmd_fp)
	    G_fatal_error(_("Unable to open input file <%s>"), opt.input->answer);
    }

    if (isatty(fileno(cmd_fp)))
	fprintf(stderr,
		_("\nPlease enter text instructions.  Enter EOF (ctrl-d) on last line to quit\n"));

    set_x = set_y = set_l = 0;
    first_text = 1;
    linefeed = 1;
    /* do the plotting */
    while (fgets(buf, sizeof(buf), cmd_fp)) {
	int buf_len;
	char *buf_ptr, *ptr;

	buf_len = strlen(buf) - 1;
	for (; buf[buf_len] == '\r' || buf[buf_len] == '\n'; buf_len--) ;
	buf[buf_len + 1] = 0;

	if (buf[0] == '.' && buf[1] != '.') {
	    int i;
	    double d;

	    G_squeeze(buf);	/* added 6/91 DBS @ CWU */
	    for (buf_ptr = buf + 2; *buf_ptr == ' '; buf_ptr++) ;
	    buf_len = strlen(buf_ptr);

	    switch (buf[1] & 0x7f) {
	    case 'F':
		/* font */
		if ((ptr = strchr(buf_ptr, ':')))
		    *ptr = 0;
		D_font(buf_ptr);
		if (ptr)
		    D_encoding(ptr + 1);
		break;
	    case 'C':
		/* color */
		set_color(buf_ptr);
		fg_color = D_parse_color(buf_ptr, 1);
		break;
	    case 'G':
		/* background color */
		bg_color = D_parse_color(buf_ptr, 1);
		do_background = 1;
		break;
	    case 'S':
		/* size */
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] != 'p')
#ifdef BACKWARD_COMPATIBILITY
		    d *= (win.b - win.t) / 100.0 / linespacing;
#else
		    d *= (win.b - win.t) / 100.0;
#endif
		size = d + (i ? size : 0);
		D_text_size(size, size);
		break;
	    case 'B':
		/* bold */
		bold = (atoi(buf_ptr) ? 1 : 0);
		break;
	    case 'A':
		/* align */
		strncpy(align, buf_ptr, 2);
		break;
	    case 'R':
		/* rotation */
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] != 'r')
		    d *= M_PI / 180.0;
		d += (i ? rotation : 0.0);
		rotation = fmod(d, 2.0 * M_PI);
		if (rotation < 0.0)
		    rotation += 2.0 * M_PI;
		D_text_rotation(rotation * 180.0 / M_PI);
		break;
	    case 'I':
		/* linespacing */
		linespacing = atof(buf_ptr);
		break;
	    case 'X':
		/* x */
		set_l = 0;
		set_x = 1;
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] == '%')
		    /* percentage */
		    d *= (win.r - win.l) / 100.0;
		else if (buf_ptr[buf_len - 1] != 'p')
		    /* column */
		    d = (d - 1) * size * linespacing + 0.5;
		x = prev_x = d + (i ? x : orig_x);
		break;
	    case 'Y':
		/* y */
		set_l = 0;
		set_y = 1;
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] == '%')
		    /* percentage */
		    d = win.b - d * (win.b - win.t) / 100.0;
		else if (buf_ptr[buf_len - 1] != 'p')
		    /* row */
		    d *= size * linespacing + 0.5;
		y = prev_y = d + (i ? y : orig_y);
		break;
	    case 'L':
		/* linefeed */
		set_l = 1;
		linefeed = (atoi(buf_ptr) ? 1 : 0);
		break;
	    case 'E':
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] == '%')
		    d *= (win.r - win.l) / 100.0;
		else if (buf_ptr[buf_len - 1] != 'p')
		    d = D_u_to_d_col(d);
		x = prev_x = orig_x = d + (i ? orig_x : win.l);
		break;
	    case 'N':
		i = 0;
		if (strchr("+-", buf_ptr[0]))
		    i = 1;
		d = atof(buf_ptr);
		if (buf_ptr[buf_len - 1] == '%')
		    d *= (win.b - win.t) / 100.0;
		else if (buf_ptr[buf_len - 1] != 'p')
		    d = D_u_to_d_row(d);
		y = prev_y = orig_y = d + (i ? orig_y : win.t);
		break;
	    }
	}
	else {
	    buf_ptr = buf;
	    if (buf[0] == '.' && buf[1] == '.')
		buf_ptr++;

	    if (!first_text && (linefeed || set_l)) {
		/* if x is not given, increment x */
		if (!set_x)
		    x = prev_x +
			(size * linespacing + 0.5) * sin(rotation);
		/* if y is not given, increment y */
		if (!set_y)
		    y = prev_y +
			(size * linespacing + 0.5) * cos(rotation);
		prev_x = x;
		prev_y = y;
	    }
	    set_x = set_y = set_l = first_text = 0;

	    draw_text(buf_ptr, &x, &y, size, align, rotation, bold, do_background, fg_color, bg_color);
	}
    }

    if (cmd_fp != stdin)
	fclose(cmd_fp);

    /* reset */
    D_text_size(5, 5);
    D_text_rotation(0.0);

    D_close_driver();

    exit(EXIT_SUCCESS);
}
Пример #2
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);
}
Пример #3
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *start_opt, *select_opt, *stop_opt, *output_opt,
        *width_opt, *height_opt, *bgcolor_opt, *res_opt;
    struct Flag *list_flag, *selected_flag, *select_flag, *release_flag, 
        *cmd_flag, *truecolor_flag, *update_flag, *x_flag, *sfile_flag;
    
    int nopts, ret;
    const char *mon;
    
    G_gisinit(argv[0]);
    
    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("graphics"));
    G_add_keyword(_("monitors"));
    module->description = _("Controls graphics display monitors from the command line.");
    
    start_opt = G_define_option();
    start_opt->key = "start";
    start_opt->type = TYPE_STRING;
    start_opt->description = _("Name of monitor to start");
    start_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    start_opt->guisection = _("Manage");
    
    stop_opt = G_define_option();
    stop_opt->key = "stop";
    stop_opt->type = TYPE_STRING;
    stop_opt->description = _("Name of monitor to stop");
    stop_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    stop_opt->guisection = _("Manage");

    select_opt = G_define_option();
    select_opt->key = "select";
    select_opt->type = TYPE_STRING;
    select_opt->description = _("Name of monitor to select");
    select_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    select_opt->guisection = _("Manage");

    width_opt = G_define_option();
    width_opt->key = "width";
    width_opt->label = _("Width for display monitor if not set by GRASS_RENDER_WIDTH");
    width_opt->description = _("Default value: 720");
    width_opt->type = TYPE_INTEGER;
    width_opt->key_desc = "value";
    width_opt->guisection = _("Settings");

    height_opt = G_define_option();
    height_opt->key = "height";
    height_opt->label = _("Height for display monitor if not set by GRASS_RENDER_HEIGHT");
    height_opt->description = _("Default value: 480");
    height_opt->type = TYPE_INTEGER;
    height_opt->key_desc = "value";
    height_opt->guisection = _("Settings");

    res_opt = G_define_option();
    res_opt->key = "resolution";
    res_opt->label = _("Dimensions of display monitor versus current size");
    res_opt->description = _("Example: resolution=2 enlarge display monitor twice to 1280x960"); 
    res_opt->type = TYPE_INTEGER;
    res_opt->key_desc = "value";
    res_opt->guisection = _("Settings");

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

    output_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    output_opt->required = NO;
    output_opt->label = _("Name for output file (when starting new monitor)");
    output_opt->description = _("Ignored for 'wx' monitors");
    output_opt->guisection = _("Settings");
    
    list_flag = G_define_flag();
    list_flag->key = 'l';
    list_flag->description = _("List running monitors and exit");
    list_flag->guisection = _("Print");

    selected_flag = G_define_flag();
    selected_flag->key = 'p';
    selected_flag->description = _("Print name of currently selected monitor and exit");
    selected_flag->guisection = _("Print");

    cmd_flag = G_define_flag();
    cmd_flag->key = 'c';
    cmd_flag->description = _("Print commands for currently selected monitor and exit");
    cmd_flag->guisection = _("Print");

    sfile_flag = G_define_flag();
    sfile_flag->key = 'g';
    sfile_flag->description =
	_("Print path to support files of currently selected monitor and exit");

    select_flag = G_define_flag();
    select_flag->key = 's';
    select_flag->description = _("Do not automatically select when starting");
    select_flag->guisection = _("Manage");

    release_flag = G_define_flag();
    release_flag->key = 'r';
    release_flag->description = _("Release and stop currently selected monitor and exit");
    release_flag->guisection = _("Manage");

    truecolor_flag = G_define_flag();
    truecolor_flag->key = 't';
    truecolor_flag->description = _("Disable true colors");
    truecolor_flag->guisection = _("Settings");

    update_flag = G_define_flag();
    update_flag->key = 'u';
    update_flag->label = _("Open output file in update mode");
    update_flag->description = _("Requires --overwrite flag");
    update_flag->guisection = _("Settings");

    x_flag = G_define_flag();
    x_flag->key = 'x';
    x_flag->label = _("Launch light-weight wx monitor without toolbars and statusbar");
    x_flag->description = _("Requires 'start=wx0-7'");
    x_flag->guisection = _("Settings");

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

    if (x_flag->answer && start_opt->answer && strncmp(start_opt->answer, "wx", 2) != 0)
        G_warning(_("Flag -%c has effect only for wx monitors (%s=wx0-7)"),
                  x_flag->key, start_opt->key);
            
    if (selected_flag->answer || release_flag->answer ||
        cmd_flag->answer || sfile_flag->answer) {
	if (list_flag->answer)
	    G_warning(_("Flag -%c ignored"), list_flag->key);
	mon = G_getenv_nofatal("MONITOR");
	if (mon) {
	    if (selected_flag->answer) {
		G_verbose_message(_("Currently selected monitor:"));
		fprintf(stdout, "%s\n", mon);
	    }
	    else if (cmd_flag->answer) {
		G_message(_("List of commands for monitor <%s>:"), mon);
		list_cmd(mon, stdout);
	    }
            else if (sfile_flag->answer) {
                list_files(mon, stdout);
            }
	    else if (mon) { /* release */
		G_unsetenv("MONITOR");
		G_verbose_message(_("Monitor <%s> released"), mon); 
                ret = stop_mon(mon);
	    }
	}
	else
	    G_important_message(_("No monitor selected"));
	
	exit(EXIT_SUCCESS);
    }

    if (list_flag->answer) {
	print_list(stdout);
	exit(EXIT_SUCCESS);
    }
	
    nopts = 0;
    if (start_opt->answer)
	nopts++;
    if (stop_opt->answer)
	nopts++;
    if (select_opt->answer)
	nopts++;

    if (nopts != 1)
	G_fatal_error(_("Either <%s>, <%s> or <%s> must be given"),
		      start_opt->key, stop_opt->key, select_opt->key);
    
    if (output_opt->answer &&
	(!start_opt->answer || strncmp(start_opt->answer, "wx", 2) == 0))
	G_warning(_("Option <%s> ignored"), output_opt->key);
    
    if (start_opt->answer) {
        int width, height;

        width = width_opt->answer ? atoi(width_opt->answer) : 0;
        height = height_opt->answer ? atoi(height_opt->answer) : 0;
        if (width < 1) {
            char *env_width = getenv("GRASS_RENDER_WIDTH");
            if (env_width)
                width = atoi(env_width);
        }
        if (height < 1) {
            char *env_height = getenv("GRASS_RENDER_HEIGHT");
            if (env_height)
                height = atoi(env_height);
        }
        if (width < 1)
            width = DEFAULT_WIDTH;
        if (height < 1)
            height = DEFAULT_HEIGHT;
        
        if (res_opt->answer) {
            int res;
            
            res = atoi(res_opt->answer);
            width *= res;
            height *= res;
        }

        G_debug(1, "Monitor width/height = %d/%d", width, height);

	ret = start_mon(start_opt->answer, output_opt->answer, !select_flag->answer,
			width, height, bgcolor_opt->answer,
			!truecolor_flag->answer, x_flag->answer, update_flag->answer);
        if (output_opt->answer && !update_flag->answer) {
            D_open_driver();
            D_setup_unity(0);
            D_erase(bgcolor_opt->answer);
            D_close_driver();
        }
    }
    
    if (stop_opt->answer)
	ret = stop_mon(stop_opt->answer);
    
    if (select_opt->answer)
	ret = select_mon(select_opt->answer);
    
    if (ret != 0)
	exit(EXIT_FAILURE);
    
    exit(EXIT_SUCCESS);
}
Пример #4
0
int draw_n_arrow(double east, double north, double fontsize,
		 char *n_arrow_num, double line_width)
{
    double x_pos, y_pos;
    double t, b, l, r;
    double tt, tb, tl, tr; /* text box*/

    SYMBOL *Symb;
    RGBA_Color *line_color, *fill_color;
    int R, G, B;
    double x0, y0;
    char icon[64];
    double symbol_size;


    /* Establish text size */
    if (fontsize > 0)
	D_text_size(fontsize, fontsize);

    D_setup_unity(0);
    D_get_src(&t, &b, &l, &r);

    x_pos = east * (r - l) / 100.;
    y_pos = (100. - north) * (b - t) / 100.;

    if (line_width > 0)
	D_line_width(line_width);

    if (fontsize > 0) {
    	/* draw the "N" */
    	D_get_text_box("N", &tt, &tb, &tl, &tr);
    	D_use_color(fg_color);

    	/* positions manually tuned */
    	switch (n_arrow_num[0]) {
    	case '1':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 45);
    	    D_text("N");
    	    break;
    	case '3':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 60);
    	    D_text("N");
    	    break;
    	case '4':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 45);
    	    D_text("N");
    	    break;
    	case '7':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 70);
    	    D_text("N");
    	    break;
    	case '9':
	case 'f':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 55);
    	    D_text("N");
	    break;
    	case 'b':
    	    D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 48.5);
    	    D_text("N");
    	    break;
    	case '2':
    	case '5':
    	case '6':
    	case '8':
    	    break;
    	default:
    	    G_fatal_error(_("Could not parse symbol"));
    	}
    }

    /* display the north arrow symbol */
    line_color = G_malloc(sizeof(RGBA_Color));
    fill_color = G_malloc(sizeof(RGBA_Color));

    if (D_color_number_to_RGB(fg_color, &R, &G, &B) == 0)
    	/* fall back to black on failure */
    	G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
    line_color->r = (unsigned char)R;
    line_color->g = (unsigned char)G;
    line_color->b = (unsigned char)B;
    line_color->a = RGBA_COLOR_OPAQUE;

    if (D_color_number_to_RGB(bg_color, &R, &G, &B) == 0)
    	/* fall back to black on failure */
    	G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
    fill_color->r = (unsigned char)R;
    fill_color->g = (unsigned char)G;
    fill_color->b = (unsigned char)B;
    fill_color->a = RGBA_COLOR_OPAQUE;

    if (n_arrow_num[0] == '2' || n_arrow_num[0] == '9')
    	fill_color->a = RGBA_COLOR_TRANSPARENT;

    /* sizes manually tuned */
    switch (n_arrow_num[0]) {
    case '1':
    	symbol_size = 35.;
    	break;
    case '2':
    	symbol_size = 19.;
    	break;
    case '3':
    	symbol_size = 20.;
    	break;
    case '4':
    	symbol_size = 15.;
    	break;
    case '5':
    case '6':
    	symbol_size = 14.;
    	break;
    case '7':
    	symbol_size = 23.;
    	break;
    case '8':
    case '9':
    	symbol_size = 17.;
    	break;
    case 'b':
    	symbol_size = 80.;
    	break;
    case 'f':
    	symbol_size = 100.;
    	break;
    default:
    	G_fatal_error(_("Could not parse symbol"));
    }

    x0 = D_d_to_u_col(x_pos);
    y0 = D_d_to_u_row(y_pos);

    if (n_arrow_num[0] == 'b')
	strcpy(icon, "n_arrows/basic_compass");
    else if (n_arrow_num[0] == 'f')
	strcpy(icon, "n_arrows/fancy_compass");
    else {
	strcpy(icon, "n_arrows/n_arrow");
	strncat(icon, n_arrow_num, 32);
    }

    Symb = S_read(icon);

    if(!Symb)
    	G_fatal_error(_("Could not read symbol \"%s\""), icon);

    S_stroke(Symb, symbol_size, 0.0, 0);
    D_symbol(Symb, x0, y0, line_color, fill_color);


    if (line_width > 0)
	D_line_width(0);

    G_free(Symb);
    G_free(line_color);
    G_free(fill_color);

    return 0;
}
Пример #5
0
int main(int argc, char **argv)
{
    char *map_name;
    int color;
    int lines;
    int cols;

    struct FPRange fp_range;
    struct Colors colors;
    double ratio;
    DCELL dmin, dmax, dval;
    int cats_num;
    int cur_dot_row, cur_dot_col;
    int dots_per_line, dots_per_col;
    int atcat;
    int white, black;
    int atcol, atline;
    int count, offset;
    double t, b, l, r;
    int fp, new_colr;
    double x_box[5], y_box[5];

    struct GModule *module;
    struct Option *opt1, *opt2, *opt3, *opt4;
    struct Flag *skip_null;

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

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("raster"));
    module->description =
	_("Displays the color table associated with a raster map layer.");

    opt1 = G_define_standard_option(G_OPT_R_MAP);
    opt1->description =
	_("Name of raster map whose color table is to be displayed");

    opt2 = G_define_option();
    opt2->key = "color";
    opt2->type = TYPE_STRING;
    opt2->answer = DEFAULT_BG_COLOR;
    opt2->gisprompt = "old_color,color,color";
    opt2->description =
	_("Color of lines separating the colors of the color table");

    opt3 = G_define_option();
    opt3->key = "lines";
    opt3->type = TYPE_INTEGER;
    opt3->options = "1-1000";
    opt3->description = _("Number of lines to appear in the color table");

    opt4 = G_define_option();
    opt4->key = "cols";
    opt4->type = TYPE_INTEGER;
    opt4->options = "1-1000";
    opt4->description = _("Number of columns to appear in the color table");

    skip_null = G_define_flag();
    skip_null->key = 'n';
    skip_null->description =
	_("Don't draw a collar showing the NULL color in FP maps");

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


    map_name = opt1->answer;
    fp = Rast_map_is_fp(map_name, "");

    if (opt2->answer != NULL) {
	new_colr = D_translate_color(opt2->answer);
	color = new_colr;
    }

    if (fp)
	lines = 1;
    else
	lines = 0;

    if (opt3->answer != NULL) {
	if (fp)
	    G_warning(_("<%s> is floating-point; "
			"ignoring [lines] and drawing continuous color ramp"),
		      map_name);
	else
	    sscanf(opt3->answer, "%d", &lines);
    }

    if (fp)
	cols = 1;
    else
	cols = 0;

    if (opt4->answer) {
	if (fp)
	    G_warning(_("<%s> is floating-point; "
			"ignoring [cols] and drawing continuous color ramp"),
		      map_name);
	else
	    sscanf(opt4->answer, "%d", &cols);
    }

    /* Make sure map is available */
    if (Rast_read_colors(map_name, "", &colors) == -1)
	G_fatal_error(_("Color file for <%s> not available"), map_name);
    if (Rast_read_fp_range(map_name, "", &fp_range) == -1)
	G_fatal_error(_("Range file for <%s> not available"), map_name);
    if (D_open_driver() != 0)
	G_fatal_error(_("No graphics device selected. "
			"Use d.mon to select graphics device."));

    D_setup_unity(0);
    D_get_src(&t, &b, &l, &r);

    Rast_get_fp_range_min_max(&fp_range, &dmin, &dmax);
    if (Rast_is_d_null_value(&dmin) || Rast_is_d_null_value(&dmax))
	G_fatal_error(_("Data range is empty"));

    cats_num = (int)dmax - (int)dmin + 1;

    if (lines <= 0 && cols <= 0) {
	double dx, dy;

	dy = (double)(b - t);
	dx = (double)(r - l);
	ratio = dy / dx;
	cols = 1 + sqrt((dmax - dmin + 1.) / ratio);
	lines = 1 + cats_num / cols;
    }
    else if (lines > 0 && cols <= 0) {
	cols = 1 + cats_num / lines;
    }
    else if (cols > 0 && lines <= 0) {
	lines = 1 + cats_num / cols;
    }
    /* otherwise, accept without complaint what the user requests
     * It is possible that the number of lines and cols is not
     * sufficient for the number of categories.
     */

    dots_per_line = (b - t) / lines;
    dots_per_col = (r - l) / cols;

    x_box[0] = 0;			y_box[0] = 0;
    x_box[1] = 0;			y_box[1] = (6 - dots_per_line);
    x_box[2] = (dots_per_col - 6);	y_box[2] = 0;
    x_box[3] = 0;			y_box[3] = (dots_per_line - 6);
    x_box[4] = (6 - dots_per_col);	y_box[4] = 0;

    white = D_translate_color("white");
    black = D_translate_color("black");
    Rast_set_c_null_value(&atcat, 1);

    if (!fp) {
	for (atcol = 0; atcol < cols; atcol++) {
	    cur_dot_row = t;
	    cur_dot_col = l + atcol * dots_per_col;
	    count = 0;
	    for (atline = 0; atline < lines; atline++) {
		cur_dot_row += dots_per_line;
		/* Draw outer border box */
		D_use_color(color);
		D_begin();
		D_move_abs(cur_dot_col + 2, (cur_dot_row - 1));
		D_cont_rel(0, (2 - dots_per_line));
		D_cont_rel((dots_per_col - 2), 0);
		D_cont_rel(0, (dots_per_line - 2));
		D_cont_rel((2 - dots_per_col), 0);
		D_end();
		D_stroke();
		/* Draw black box */
		D_use_color(black);
		D_begin();
		D_move_abs(cur_dot_col + 3, (cur_dot_row - 2));
		D_cont_rel(0, (4 - dots_per_line));
		D_cont_rel((dots_per_col - 4), 0);
		D_cont_rel(0, (dots_per_line - 4));
		D_cont_rel((4 - dots_per_col), 0);
		D_end();
		D_stroke();
		/* Color box */
		D_color((CELL) atcat, &colors);
		D_pos_abs(cur_dot_col + 4, (cur_dot_row - 3));
		D_polygon_rel(x_box, y_box, 5);

		count++;
		/* first cat number is null value */
		if (count == 1)
		    atcat = (int)dmin;
		else if (++atcat > (int)dmax)
		    break;
	    }
	    if (atcat > (int)dmax)
		break;
	} /* col loop */
    } /* int map */

    else {
	/*** draw continuous color ramp for fp map ***/

	cur_dot_row = t + dots_per_line;
	cur_dot_col = l;
	/* Draw outer border box */
	D_use_color(color);
	D_begin();
	D_move_abs(cur_dot_col + 1, (cur_dot_row - 1));
	D_cont_rel(0, (2 - dots_per_line));
	D_cont_rel((dots_per_col - 2), 0);
	D_cont_rel(0, (dots_per_line - 2));
	D_cont_rel((2 - dots_per_col), 0);
	D_end();
	D_stroke();
	/* Draw black box */
	D_use_color(black);
	D_begin();
	D_move_abs(cur_dot_col + 2, (cur_dot_row - 2));
	D_cont_rel(0, (4 - dots_per_line));
	D_cont_rel((dots_per_col - 4), 0);
	D_cont_rel(0, (dots_per_line - 4));
	D_cont_rel((4 - dots_per_col), 0);
	D_end();
	D_stroke();

	/* Color ramp box */
	  /* get separate color for each pixel */
	  /* fisrt 5 pixels draw null color */
	y_box[1] = -1;
	y_box[3] = 1;
	x_box[2] = (dots_per_col - 6);
	x_box[4] = (6 - dots_per_col);

	G_debug(1, "dots_per_line: %d  dmin=%.2f dmax=%.2f",
		dots_per_line, dmin, dmax);

	if (skip_null->answer)
	    offset = 1;
	else
	    offset = 4;

	for (r = 0; r < dots_per_line - 6; r++) {
	    if ((r <= 4) && !skip_null->answer)
		Rast_set_d_null_value(&dval, 1);
	    else
		dval =
		    dmin +  r*(dmax - dmin) / (dots_per_line - 6 - offset);

	    D_d_color(dval, &colors);
	    D_pos_abs(cur_dot_col + 3, (cur_dot_row - 3) - r);
	    D_polygon_rel(x_box, y_box, 5);
	}
    }
    
    D_save_command(G_recreate_command());
    D_close_driver();

    exit(EXIT_SUCCESS);
}
Пример #6
0
int main(int argc, char **argv)
{
    double xoffset;		/* offset for x-axis */
    double yoffset;		/* offset for y-axis */
    double text_height;
    double text_width;
    int i;
    int j;
    int c;
    int tic_every;
    int max_tics;
    int title_color;
    int num_y_files;
    int tic_unit;
    double t, b, l, r;
    double tt, tb, tl, tr;
    double prev_x, prev_y[11];
    double new_x, new_y[11];
    int line;
    double x_line[3];
    double y_line[3];
    int err;

    struct in_file
    {
	int num_pnts;		/* number of lines in file  */
	int color;		/* color to use for y lines */
	float max;		/* maximum value in file    */
	float min;		/* minimum value in file    */
	float value;		/* current value read in    */
	char name[1024];	/* name of file      */
	char full_name[1024];	/* path/name of file    */
	FILE *fp;		/* pointer to file        */
    };

    struct in_file in[12];
    struct GModule *module;

    float max_y;
    float min_y;
    float height, width;
    float xscale;
    float yscale;

    char txt[1024], xlabel[512];
    char tic_name[1024];
    char *name;
    char color_name[20];

    FILE *fopen();

    struct Option *dir_opt, *x_opt, *y_opt;
    struct Option *y_color_opt;
    struct Option *title[3];
    struct Option *t_color_opt;

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

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("cartography"));
    module->description =
	_("Generates and displays simple line graphs in the active graphics monitor display frame.");

    x_opt = G_define_option();
    x_opt->key = "x_file";
    x_opt->description = _("Name of data file for X axis of graph");
    x_opt->type = TYPE_STRING;
    x_opt->required = YES;

    y_opt = G_define_option();
    y_opt->key = "y_file";
    y_opt->description = _("Name of data file(s) for Y axis of graph");
    y_opt->type = TYPE_STRING;
    y_opt->required = YES;
    y_opt->multiple = YES;

    dir_opt = G_define_option();
    dir_opt->key = "directory";
    dir_opt->description = _("Path to file location");
    dir_opt->type = TYPE_STRING;
    dir_opt->required = NO;
    /* Remove answer because create problem with full path */
    /* dir_opt->answer = "."; */

    y_color_opt = G_define_option();
    y_color_opt->key = "y_color";
    y_color_opt->description = _("Color for Y data");
    y_color_opt->type = TYPE_STRING;
    y_color_opt->required = NO;
    y_color_opt->multiple = YES;
    y_color_opt->gisprompt = "old_color,color,color";
    y_color_opt->answers = NULL;

    t_color_opt = G_define_option();
    t_color_opt->key = "title_color";
    t_color_opt->description = _("Color for axis, tics, numbers, and title");
    t_color_opt->type = TYPE_STRING;
    t_color_opt->required = NO;
    t_color_opt->gisprompt = "old_color,color,color";
    t_color_opt->answer = DEFAULT_FG_COLOR;

    title[0] = G_define_option();
    title[0]->key = "x_title";
    title[0]->description = _("Title for X data");
    title[0]->type = TYPE_STRING;
    title[0]->required = NO;
    title[0]->answer = "";

    title[1] = G_define_option();
    title[1]->key = "y_title";
    title[1]->description = _("Title for Y data");
    title[1]->type = TYPE_STRING;
    title[1]->required = NO;
    title[1]->answer = "";

    title[2] = G_define_option();
    title[2]->key = "title";
    title[2]->description = _("Title for Graph");
    title[2]->type = TYPE_STRING;
    title[2]->required = NO;
    title[2]->answer = "";


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

    for (i = 0; i < 3; i++) {
	for (j = 0; j < strlen(title[i]->answer); j++)
	    if (title[i]->answer[j] == '_')
		title[i]->answer[j] = ' ';
    }

    /* build path to X data file and open for reading
       notice that in[0] will be the X file, and in[1-10]
       will be the Y file(s) */

    if (dir_opt->answer != NULL) {
	sprintf(in[0].full_name, "%s/%s", dir_opt->answer, x_opt->answer);
    } else {
	sprintf(in[0].full_name, "%s", x_opt->answer);
    }
    sprintf(in[0].name, "%s", x_opt->answer);

    if ((in[0].fp = fopen(in[0].full_name, "r")) == NULL)
	G_fatal_error(_("Unable to open input file <%s>"), in[0].full_name);

    num_y_files = 0;

    /* open all Y data files */

    for (i = 0, j = 1; (name = y_opt->answers[i]); i++, j++) {
      
	if (dir_opt->answer != NULL) {
	    sprintf(in[j].full_name, "%s/%s", dir_opt->answer, name);
	} else {
	    sprintf(in[j].full_name, "%s", name);
	}
	sprintf(in[j].name, "%s", name);

	if ((in[j].fp = fopen(in[j].full_name, "r")) == NULL)
	    G_fatal_error(_("Unable to open input file <%s>"),
			  in[j].full_name);

	num_y_files++;
	if (num_y_files > 10)
	    G_fatal_error(_("Maximum of 10 Y data files exceeded"));
    }

    /* set colors  */

    title_color = D_translate_color(t_color_opt->answer);

    /* I had an argument with the parser, and couldn't get a neat list of
       the input colors as I thought I should. I did a quick hack to get
       my list from the answer var, which gives us the colors input
       separated by commas. at least we know that they have been checked against
       the list of possibles */
    c = 0;
    j = 1;
    if (y_color_opt->answer != NULL) {
	for (i = 0; i <= (strlen(y_color_opt->answer)); i++) {
	    if ((y_color_opt->answer[i] == ',') ||
		(i == (strlen(y_color_opt->answer)))) {
		color_name[c] = '\0';
		in[j].color = D_translate_color(color_name);
		j++;
		c = 0;
	    }
	    else {
		color_name[c++] = y_color_opt->answer[i];
	    }
	}
	/* this is lame. I could come up with a color or prompt for one or something */
	if (j < num_y_files)
	    G_fatal_error(_("Only <%d> colors given for <%d> lines"), j,
			  num_y_files);
    }
    else
	/* no colors given on command line, use default list */
    {
	for (i = 1; i <= num_y_files; i++) {
	    in[i].color = default_y_colors[i];
	}
    }

    /* get coordinates of current screen window, in pixels */
    D_open_driver();
    
    D_setup_unity(0);
    D_get_src(&t, &b, &l, &r);

    /* create axis lines, to be drawn later */
    height = b - t;
    width = r - l;
    x_line[0] = x_line[1] = l + (ORIGIN_X * width);
    x_line[2] = l + (XAXIS_END * width);
    y_line[0] = b - (YAXIS_END * height);
    y_line[1] = y_line[2] = b - (ORIGIN_Y * height);
    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH;
    D_text_size(text_width, text_height);

    /* read thru each data file in turn, find max and min values for
       each, count lines, find x min and max, find overall y min and
       max */

    max_y = -99999.9;
    min_y = 99999.9;

    for (i = 0; i <= num_y_files; i++) {

	in[i].min = 99999.9;
	in[i].max = -99999.9;
	in[i].value = 0.0;
	in[i].num_pnts = 0;

	while ((err = fscanf(in[i].fp, "%f", &in[i].value)) != EOF) {
	    in[i].num_pnts++;
	    in[i].max = MAX(in[i].max, in[i].value);
	    in[i].min = MIN(in[i].min, in[i].value);
	    if (i > 0) {	/* if we have a y file */
		min_y = MIN(min_y, in[i].value);
		max_y = MAX(max_y, in[i].value);
	    }
	}
	if ((i > 0) && (in[0].num_pnts != in[i].num_pnts)) {
        if (in[i].num_pnts < in[0].num_pnts) {
            G_warning(_("Y input file <%s> contains fewer data points than the X input file"),
		      in[i].name);
        }
        else {
            G_warning(_("Y input file <%s> contains more data points than the X input file"),
		      in[i].name);
        }
        
	    if (in[i].num_pnts > in[0].num_pnts)
		G_message(n_("The last point will be ignored", 
                     "The last %d points will be ignored",
                     (in[i].num_pnts - in[0].num_pnts)),
			  (in[i].num_pnts - in[0].num_pnts));
	}
    }

    /* close all files */

    for (i = 0; i <= num_y_files; i++)
	fclose(in[i].fp);

    /* figure scaling factors and offsets */

    xscale = ((double)(x_line[2] - x_line[1]) / (double)(in[0].num_pnts));
    yscale = ((double)(y_line[1] - y_line[0]) / (max_y - min_y));
    yoffset = (double)(y_line[1]);
    xoffset = (double)(x_line[1]);

    /* figure tic_every and tic_units for the x-axis of the bar-chart.
       tic_every tells how often to place a tic-number.  tic_unit tells
       the unit to use in expressing tic-numbers. */

    if (xscale < XTIC_DIST) {
	max_tics = (x_line[2] - x_line[1]) / XTIC_DIST;
	i = 1;
	while (((in[0].max - in[0].min) / tics[i].every) > max_tics)
	    i++;
	tic_every = tics[i].every;
	tic_unit = tics[i].unit;
	strcpy(tic_name, tics[i].name);
    }
    else {
	tic_every = 1;
	tic_unit = 1;
	strcpy(tic_name, "");
    }


    /* open all the data files again */

    for (i = 0; i <= num_y_files; i++) {
	if ((in[i].fp = fopen(in[i].full_name, "r")) == NULL) {
	    D_close_driver();
	    G_fatal_error(_("Unable to open input file <%s>"), in[i].full_name);
	}
    }

    /* loop through number of lines in x data file, 
       then loop thru for each y file, drawing a piece of each line and a
       legend bar on each iteration evenly divisible, a tic-mark
       on those evenly divisible by tic_unit, and a tic_mark
       number on those evenly divisible by tic_every   */

    /* read the info from the inputs */

    for (line = 0; line < in[0].num_pnts; line++) {
	/* scan in an X value */
	err = fscanf(in[0].fp, "%f", &in[0].value);

	/* didn't find a number or hit EOF before our time */
	if ((err != 1) || (err == EOF)) {
	    D_close_driver();
	    G_fatal_error(_("Problem reading X data file at line %d"), line);
	}

	/* for each Y data file, get a value and compute where to draw it */
	for (i = 1; i <= num_y_files; i++) {
	    /* check to see that we do indeed have data for this point */
	    if (line < in[i].num_pnts) {
		err = fscanf(in[i].fp, "%f", &in[i].value);
		if ((in[i].num_pnts >= line) && (err != 1)) {
		    D_close_driver();
		    G_fatal_error(_("Problem reading <%s> data file at line %d"),
				  in[i].name, line);
		}

		/* in case the Y file has fewer lines than the X file, we will skip
		   trying to draw when we run out of data */

		/* draw increment of each Y file's data */

		D_use_color(in[i].color);

		/* find out position of where Y should be drawn. */
		/* if our minimum value of y is not negative, this is easy */

		if (min_y >= 0)
		    new_y[i] =
			(yoffset - yscale * (in[i].value - min_y));

		/* if our minimum value of y is negative, then we have two
		   cases:  our current value to plot is pos or neg */

		else {
		    if (in[i].value < 0)
			new_y[i] = (yoffset - yscale * (-1 *
							     (min_y -
							      in[i].value)));
		    else
			new_y[i] = (yoffset - yscale * (in[i].value +
							     (min_y * -1)));
		}

		new_x = xoffset + (line * xscale);
		if (line == 0) {
		    prev_x = xoffset;
		    prev_y[i] = yoffset;
		}
		D_line_abs(prev_x, prev_y[i], new_x, new_y[i]);
		prev_y[i] = new_y[i];
	    }
	}
	prev_x = new_x;

	/* draw x-axis tic-marks and numbers */

	if (rem((long int)in[0].value, tic_every) == 0.0) {

	    /* draw a numbered tic-mark */

	    D_use_color(title_color);
	    D_begin();
	    D_move_abs(xoffset + line * xscale, b - ORIGIN_Y * (b - t));
	    D_cont_rel(0, BIG_TIC * (b - t));
	    D_end();
	    D_stroke();

	    if ((in[0].value >= 1) || (in[0].value <= -1) ||
		(in[0].value == 0))
		sprintf(txt, "%.0f", (in[0].value / tic_unit));
	    else
		sprintf(txt, "%.2f", (in[0].value));
	    text_height = (b - t) * TEXT_HEIGHT;
	    text_width = (r - l) * TEXT_WIDTH;
	    D_text_size(text_width, text_height);
	    D_get_text_box(txt, &tt, &tb, &tl, &tr);
	    while ((tr - tl) > XTIC_DIST) {
		text_width *= 0.75;
		text_height *= 0.75;
		D_text_size(text_width, text_height);
		D_get_text_box(txt, &tt, &tb, &tl, &tr);
	    }
	    D_pos_abs((xoffset + (line * xscale - (tr - tl) / 2)),
		       (b - XNUMS_Y * (b - t)));
	    D_text(txt);
	}
	else if (rem(line, tic_unit) == 0.0) {

	    /* draw a tic-mark */

	    D_use_color(title_color);
	    D_begin();
	    D_move_abs(xoffset + line * xscale,
		       b - ORIGIN_Y * (b - t));
	    D_cont_rel(0, SMALL_TIC * (b - t));
	    D_end();
	    D_stroke();
	}
    }

    /* close all input files */
    for (i = 0; i <= num_y_files; i++) {
	fclose(in[i].fp);
    }

    /* draw the x-axis label */
    if ((strcmp(title[0]->answer, "") == 0) && (strcmp(tic_name, "") == 0))
	*xlabel = '\0';
    else
	sprintf(xlabel, "X: %s %s", title[0]->answer, tic_name);
    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH * 1.5;
    D_text_size(text_width, text_height);
    D_get_text_box(xlabel, &tt, &tb, &tl, &tr);
    D_pos_abs((l + (r - l) / 2 - (tr - tl) / 2),
	      (b - LABEL_1 * (b - t)));
    D_use_color(title_color);
    D_text(xlabel);

    /* DRAW Y-AXIS TIC-MARKS AND NUMBERS
       first, figure tic_every and tic_units for the x-axis of the bar-chart.
       tic_every tells how often to place a tic-number.  tic_unit tells
       the unit to use in expressing tic-numbers. */

    if (yscale < YTIC_DIST) {
	max_tics = (y_line[1] - y_line[0]) / YTIC_DIST;
	i = 1;
	while (((max_y - min_y) / tics[i].every) > max_tics)
	    i++;
	tic_every = tics[i].every;
	tic_unit = tics[i].unit;
	strcpy(tic_name, tics[i].name);
    }
    else {
	tic_every = 1;
	tic_unit = 1;
	strcpy(tic_name, "");
    }

    /* Y-AXIS LOOP */

    for (i = (int)min_y; i <= (int)max_y; i += tic_unit) {
	if (rem(i, tic_every) == 0.0) {
	    /* draw a tic-mark */

	    D_begin();
	    D_move_abs(x_line[0], yoffset - yscale * (i - min_y));
	    D_cont_rel(-(r - l) * BIG_TIC, 0);
	    D_end();
	    D_stroke();

	    /* draw a tic-mark number */

	    sprintf(txt, "%d", (i / tic_unit));
	    text_height = (b - t) * TEXT_HEIGHT;
	    text_width = (r - l) * TEXT_WIDTH;
	    D_text_size(text_width, text_height);
	    D_get_text_box(txt, &tt, &tb, &tl, &tr);
	    while ((tt - tb) > YTIC_DIST) {
		text_width *= 0.75;
		text_height *= 0.75;
		D_text_size(text_width, text_height);
		D_get_text_box(txt, &tt, &tb, &tl, &tr);
	    }
	    D_pos_abs(l + (r - l) * YNUMS_X - (tr - tl) / 2,
		      yoffset - (yscale * (i - min_y) + 0.5 * (tt - tb)));
	    D_text(txt);
	}
	else if (rem(i, tic_unit) == 0.0) {
	    /* draw a tic-mark */
	    D_begin();
	    D_move_abs(x_line[0], (yoffset - yscale * (i - min_y)));
	    D_cont_rel(-(r - l) * SMALL_TIC, 0);
	    D_end();
	    D_stroke();
	}
    }

    /* draw the y-axis label */
    if ((strcmp(title[1]->answer, "") == 0) && (strcmp(tic_name, "") == 0))
	*xlabel = '\0';
    else
	sprintf(xlabel, "Y: %s %s", title[1]->answer, tic_name);
    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH * 1.5;
    D_text_size(text_width, text_height);
    D_get_text_box(xlabel, &tt, &tb, &tl, &tr);
    D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2, b - LABEL_2 * (b - t));
    D_use_color(title_color);
    D_text(xlabel);

    /* top label */
    sprintf(xlabel, "%s", title[2]->answer);
    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH * 2.0;
    D_text_size(text_width, text_height);
    D_get_text_box(xlabel, &tt, &tb, &tl, &tr);
    /*
       D_move_abs((int)(((r-l)/2)-(tr-tl)/2),
       (int) (t+ (b-t)*.07) );
     */
    D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2, t + (b - t) * .07);
    D_use_color(title_color);
    D_text(xlabel);

    /* draw x and y axis lines */
    D_use_color(title_color);
    D_polyline_abs(x_line, y_line, 3);

    D_save_command(G_recreate_command());
    D_close_driver();
    
    exit(EXIT_SUCCESS);
}
Пример #7
0
int main(int argc, char **argv)
{
    struct GModule *module;
//    struct Option *opt_input, *opt_sep;
    struct Option *opt_at, *opt_cols, *opt_font, *opt_fontsize,
            *opt_fontcolor, *opt_title, *opt_tit_font, *opt_tit_fontsize, *opt_sub_font,
            *opt_sub_fontsize, *opt_bcolor, *opt_bgcolor, *opt_symb_size,
            *opt_bg_width, *opt_output, *opt_input, *opt_sep;
    struct Flag *fl_bg;

    double LL, LT;
    char *title, *file_name;
    int bcolor, bgcolor, do_bg;
    int fontsize, fontcolor, tit_size, sub_size;
    char *font, *tit_font, *sub_font;
    int cols, symb_size, bg_width;
    char *out_file;
    FILE *source;
    char buf[BUFFSIZE];
    char *sep;
    size_t nread;


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

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("cartography"));
    G_add_keyword(_("vector"));
    G_add_keyword(_("legend"));
    module->description =
    _("Displays a vector legend "
      "in the active graphics frame.");

    opt_at = G_define_option();
    opt_at->key = "at";
    opt_at->key_desc = "left,top";
    opt_at->type = TYPE_DOUBLE;
    opt_at->options = "0-100";
    opt_at->answer = "10,40";
    opt_at->required = NO;
    opt_at->description =
    _("Screen position of legend to be drawn (percentage, [0,0] is lower left)");

    opt_cols = G_define_option();
    opt_cols->key = "columns";
    opt_cols->type = TYPE_INTEGER;
    opt_cols->answer = "1";
    opt_cols->required = NO;
    opt_cols->description =
    _("Number of legend columns");
    opt_cols->guisection = _("Layout");

    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_symb_size = G_define_option();
    opt_symb_size->key = "symbol_size";
    opt_symb_size->type = TYPE_INTEGER;
    opt_symb_size->required = NO;
    opt_symb_size->description = _("Symbol size");
    opt_symb_size->answer = "20";
    opt_symb_size->guisection = _("Layout");

    opt_bcolor = G_define_standard_option(G_OPT_CN);
    opt_bcolor->key = "border_color";
    opt_bcolor->answer = "black";
    opt_bcolor->label = _("Border color");
    opt_bcolor->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");

    opt_bg_width = G_define_option();
    opt_bg_width->type = TYPE_INTEGER;
    opt_bg_width->key = "border_width";
    opt_bg_width->answer = "2";
    opt_bg_width->label = _("Background border width");
    opt_bg_width->guisection = _("Background");

    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: 12");
    opt_fontsize->guisection = _("Font settings");

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

    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: 18");
    opt_tit_fontsize->guisection = _("Title");

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

    opt_sub_fontsize = G_define_option();
    opt_sub_fontsize->key = "sub_fontsize";
    opt_sub_fontsize->type = TYPE_DOUBLE;
    opt_sub_fontsize->required = NO;
    opt_sub_fontsize->options = "1-360";
    opt_sub_fontsize->label = _("Subtitle font size");
    opt_sub_fontsize->description = _("Default: 14");
    opt_sub_fontsize->guisection = _("Font settings");

    opt_fontcolor = G_define_standard_option(G_OPT_C);
    opt_fontcolor->key = "fontcolor";
    opt_fontcolor->answer = "black";
    opt_fontcolor->label = _("Font color");
    opt_fontcolor->guisection = _("Font settings");

    fl_bg = G_define_flag();
    fl_bg->key = 'b';
    fl_bg->description = _("Display legend background");
    fl_bg->guisection = _("Background");

    opt_input = G_define_standard_option(G_OPT_F_INPUT);
    opt_input->label = _("Input legend file");
    opt_input->description = _("Path to legend file ");
    opt_input->required = NO;
    opt_input->guisection = _("In/Out");

    opt_output = G_define_standard_option(G_OPT_F_OUTPUT);
    opt_output->label = _("Output csv file");
    opt_output->description = _("Path to output file or '-' "
                                "for standard output");
    opt_output->required = NO;
    opt_output->guisection = _("In/Out");

    opt_sep = G_define_standard_option(G_OPT_F_SEP);
    opt_sep->guisection = _("In/Out");

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

    D_open_driver();
    D_setup_unity(0);

    /* parse and check options and flags */
    if (opt_at->answer) {
        sscanf(opt_at->answers[0], "%lf", &LL);
        sscanf(opt_at->answers[1], "%lf", &LT);
    }
    else {
        LL = 10;
        LT = 40;
    }

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

    if (opt_cols->answer)
        sscanf(opt_cols->answer, "%d", &cols);
    else
        cols = 1;

    sscanf(opt_symb_size->answer, "%d", &symb_size);
    sscanf(opt_bg_width->answer, "%d", &bg_width);

    /* Background */
    do_bg = fl_bg->answer;
    bcolor = D_parse_color(opt_bcolor->answer, TRUE);
    bgcolor = D_parse_color(opt_bgcolor->answer, TRUE);

    /* Font settings */
    if (opt_font->answer)
        font = opt_font->answer;
    else
        font = "sans";
    if (opt_fontsize->answer != NULL)
        sscanf(opt_fontsize->answer, "%d", &fontsize);
    else
        fontsize = 14;

    if (opt_tit_font->answer)
        tit_font = opt_tit_font->answer;
    else
        tit_font = font;
    if (opt_tit_fontsize->answer)
        sscanf(opt_tit_fontsize->answer, "%d", &tit_size);
    else
        tit_size = fontsize;

    if (opt_sub_font->answer)
        sub_font = opt_sub_font->answer;
    else
        sub_font = font;
    if (opt_sub_fontsize->answer)
        sscanf(opt_sub_fontsize->answer, "%d", &sub_size);
    else
        sub_size = fontsize;

    fontcolor = D_parse_color(opt_fontcolor->answer, FALSE); /*default color: black */

    /* I/O */
    sep = G_option_to_separator(opt_sep);

    if (opt_input->answer) {
        file_name = opt_input->answer;
        if (!file_name)
            G_fatal_error(_("Unable to open input file <%s>"), file_name);
    }
    else {
        file_name = getenv("GRASS_LEGEND_FILE");
        if (!file_name)
            G_fatal_error("No legend file defined.");
    }


    if (opt_output->answer) {
        if (strcmp(opt_output->answer,"-") == 0) {
            source = fopen(file_name, "r");
            if (!source)
                G_fatal_error(_("Unable to open input file <%s>"), file_name);
            while ((nread = fread(buf, 1, sizeof(buf), source)))
                fwrite(buf, 1, nread, stdout);
            fclose(source);
        }
        else {
            out_file = opt_output->answer;
            G_copy_file(file_name, out_file);
        }
    }

    /* Pre-calculate the layout */
    if (do_bg)
        draw(file_name, LL, LT, title, cols, bgcolor, bcolor, bg_width, 1, tit_font, tit_size, sub_font, sub_size, font, fontsize, fontcolor, symb_size, sep);

    /* Draw legend */
    draw(file_name, LL, LT, title, cols, bgcolor, bcolor, bg_width, 0, tit_font, tit_size, sub_font, sub_size, font, fontsize, fontcolor, symb_size, sep);

    D_close_driver();

    exit(EXIT_SUCCESS);
}
Пример #8
0
int draw_n_arrow(double east, double north, double rotation, char *lbl,
                 int rot_with_text, double fontsize, char *n_arrow_num,
                 double line_width)
{
    double x_pos, y_pos;
    double t, b, l, r;
    double tt, tb, tl, tr;      /* text box */

    SYMBOL *Symb;
    RGBA_Color *line_color, *fill_color;
    int R, G, B;
    double x0, y0;
    char icon[64];
    double symbol_size;


    /* Establish text size */
    if (fontsize > 0)
        D_text_size(fontsize, fontsize);

    D_setup_unity(0);
    D_get_src(&t, &b, &l, &r);

    x_pos = l + (int)(east * (r - l) / 100.);
    y_pos = t + (int)((100. - north) * (b - t) / 100.);

    if (line_width > 0)
        D_line_width(line_width);

    if (fontsize > 0) {
        /* draw the label (default "N") */
        if (rot_with_text)
            D_text_rotation(rotation * 180.0 / M_PI);
        D_get_text_box(lbl, &tt, &tb, &tl, &tr);
        D_use_color(text_color);

        /* positions manually tuned */
        switch (n_arrow_num[0]) {
        case '1':
            D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 50 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '3':
            D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 60 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '4':
            D_pos_abs(x_pos - sin(rotation) * 45 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 45 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '7':
            D_pos_abs(x_pos - sin(rotation) * 70 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 70 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '8':
            D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 60 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '9':
            D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 55 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case 'f':
            D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 55 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case 'b':
            D_pos_abs(x_pos - sin(rotation) * 48.5 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 48.5 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case 'a':
            D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 50 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case 's':
            D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
                      y_pos - cos(rotation) * 50 - (tb + tt) / 2);
            D_text(lbl);
            break;
        case '2':
        case '5':
        case '6':
            break;
        default:
            G_fatal_error(_("Could not parse symbol"));
        }
    }

    /* display the north arrow symbol */
    line_color = G_malloc(sizeof(RGBA_Color));
    fill_color = G_malloc(sizeof(RGBA_Color));

    if (D_color_number_to_RGB(fg_color, &R, &G, &B) == 0)
        line_color->a = RGBA_COLOR_TRANSPARENT;
    else
        line_color->a = RGBA_COLOR_OPAQUE;
    line_color->r = (unsigned char)R;
    line_color->g = (unsigned char)G;
    line_color->b = (unsigned char)B;


    if (D_color_number_to_RGB(bg_color, &R, &G, &B) == 0)
        fill_color->a = RGBA_COLOR_TRANSPARENT;
    else
        fill_color->a = RGBA_COLOR_OPAQUE;
    fill_color->r = (unsigned char)R;
    fill_color->g = (unsigned char)G;
    fill_color->b = (unsigned char)B;

    /* sizes manually tuned */
    switch (n_arrow_num[0]) {
    case '1':
        symbol_size = 35.;
        break;
    case '2':
        symbol_size = 19.;
        break;
    case '3':
        symbol_size = 20.;
        break;
    case '4':
        symbol_size = 15.;
        break;
    case '5':
    case '6':
        symbol_size = 14.;
        break;
    case '7':
        symbol_size = 23.;
        break;
    case '8':
    case '9':
        symbol_size = 17.;
        break;
    case 'b':
        symbol_size = 80.;
        break;
    case 'f':
        symbol_size = 100.;
        break;
    case 'a':
        if (n_arrow_num[5] == '2')
            symbol_size = 53.;
        else
            symbol_size = 70.;
        break;
    case 's':
        symbol_size = 80.;
        break;
    default:
        G_fatal_error(_("Could not parse symbol"));
    }

    x0 = D_d_to_u_col(x_pos);
    y0 = D_d_to_u_row(y_pos);

    if (n_arrow_num[0] == 'b')
        strcpy(icon, "n_arrows/basic_compass");
    else if (n_arrow_num[0] == 'f')
        strcpy(icon, "n_arrows/fancy_compass");
    else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '1')
        strcpy(icon, "basic/arrow1");
    else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '2')
        strcpy(icon, "basic/arrow2");
    else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '3')
        strcpy(icon, "basic/arrow3");
    else if (n_arrow_num[0] == 's')
        strcpy(icon, "extra/4pt_star");
    else {
        strcpy(icon, "n_arrows/n_arrow");
        strncat(icon, n_arrow_num, 32);
    }

    Symb = S_read(icon);

    if (!Symb)
        G_fatal_error(_("Could not read symbol \"%s\""), icon);

    S_stroke(Symb, symbol_size, rotation * (180 / M_PI), 0);
    D_symbol(Symb, x0, y0, line_color, fill_color);


    if (line_width > 0)
        D_line_width(0);

    G_free(Symb);
    G_free(line_color);
    G_free(fill_color);

    return 0;
}