Пример #1
0
Файл: main.c Проект: caomw/grass
static void plot_axes(void)
{
    char str[64];
    double scale;
    double t, b, l, r;

    D_use_color(D_translate_color("red"));

    D_begin();
    D_move_abs(0, 1);
    D_cont_abs(0, 0);
    D_cont_abs(1, 0);
    D_end();
    D_stroke();

    D_use_color(D_translate_color(DEFAULT_FG_COLOR));

    /* set text size for y-axis labels */
    scale = fabs(D_get_u_to_d_yconv());
    D_text_size(scale * 0.04, scale * 0.05);

    /* plot y-axis label (bottom) */
    sprintf(str, "%.1f", min);
    D_get_text_box(str, &t, &b, &l, &r);
    D_pos_abs(-0.02 - (r - l), 0 - (t - b) / 2);
    D_text(str);

    /* plot y-axis label (top) */
    sprintf(str, "%.1f", max);
    D_get_text_box(str, &t, &b, &l, &r);
    D_pos_abs(-0.02 - (r - l), 1 - (t - b) / 2);
    D_text(str);
}
Пример #2
0
void show_label(double *px, double *py, LATTR *lattr, const char *text)
{
    double X = *px, Y = *py;
    int Xoffset, Yoffset;
    double xarr[5], yarr[5];
    double T, B, L, R;

    X = X + D_get_d_to_u_xconv() * 0.5 * lattr->size;
    Y = Y + D_get_d_to_u_yconv() * 1.5 * lattr->size;

    D_pos_abs(X, Y);
    D_get_text_box(text, &T, &B, &L, &R);

    /* Expand border 1/2 of text size */
    T = T - D_get_d_to_u_yconv() * lattr->size / 2;
    B = B + D_get_d_to_u_yconv() * lattr->size / 2;
    L = L - D_get_d_to_u_xconv() * lattr->size / 2;
    R = R + D_get_d_to_u_xconv() * lattr->size / 2;

    Xoffset = 0;
    Yoffset = 0;
    if (lattr->xref == LCENTER)
	Xoffset = -(R - L) / 2;
    if (lattr->xref == LRIGHT)
	Xoffset = -(R - L);
    if (lattr->yref == LCENTER)
	Yoffset = -(B - T) / 2;
    if (lattr->yref == LBOTTOM)
	Yoffset = -(B - T);

    if (lattr->has_bgcolor || lattr->has_bcolor) {
	xarr[0] = xarr[1] = xarr[4] = L + Xoffset;
	xarr[2] = xarr[3] = R + Xoffset;
	yarr[0] = yarr[3] = yarr[4] = B + Yoffset;
	yarr[1] = yarr[2] = T + Yoffset;

	if (lattr->has_bgcolor) {
	    D_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
			lattr->bgcolor.B);
	    D_polygon_abs(xarr, yarr, 5);
	}

	if (lattr->has_bcolor) {
	    D_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
			lattr->bcolor.B);
	    D_polyline_abs(xarr, yarr, 5);
	}
	D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
    }

    D_pos_abs(X + Xoffset, Y + Yoffset);
    D_text(text);
}
Пример #3
0
static void draw_text(char *text, double *x, double *y, double size, char *align,
		      double rotation, char bold, int do_background, int fg_color, int bg_color)
{
    double w, h;
    double t, b, l, r;
    double c, s;
    int pt, pb, pl, pr;

    /* TODO: get text dimension */
    /* R_get_text_box() does not work with rotation and returns a little bit
     * bigger dimension than actual text size */
    if (rotation != 0.0)
	D_text_rotation(0.0);

    D_get_text_box(text, &t, &b, &l, &r);

    if (rotation != 0.0)
	D_text_rotation(rotation * 180.0 / M_PI);
    w = r - l;
    h = b - t;
    if (w > 0)
	w += 0.2 * size;
    else
	/* D_text() does not draw " ". */
	w = 0.8 * size;
    if (h > 0)
	h += 0.2 * size;
    else
	/* D_text() does not draw " ". */
	h = 0.8 * size;

    c = cos(rotation);
    s = sin(rotation);

    if (strcmp(align, "ll") != 0) {
	switch (align[0]) {
	case 'l':
	    break;
	case 'c':
	    *x += h / 2.0 * s;
	    *y += h / 2.0 * c;
	    break;
	case 'u':
	    *x += h * s;
	    *y += h * c;
	    break;
	}

	switch (align[1]) {
	case 'l':
	    break;
	case 'c':
	    *x -= w / 2.0 * c;
	    *y += w / 2.0 * s;
	    break;
	case 'r':
	    *x -= w * c;
	    *y += w * s;
	    break;
	}
    }

    if (do_background) {
 	pl = *x - size/2; /* some pixels margin for both sides */
 	pt = *y + size/2;
 	pr = *x + w + size/2;
 	pb = *y - h - size/2;
	D_use_color(bg_color);
 	D_box_abs(pl, pt, pr, pb);    /* draw the box */
 	D_use_color(fg_color); /* restore */
    }

    D_pos_abs(*x, *y);
    D_text(text);

    if (bold) {
	D_pos_abs(*x, *y + 1);
	D_text(text);
	D_pos_abs(*x + 1, *y);
	D_text(text);
    }

    *x += w * c;
    *y -= w * s;

    return;
}
Пример #4
0
void plot(double lon1, double lat1, double lon2, double lat2,
	  int line_color, int text_color, double factor, const char *unit)
{
    double distance;
    double text_x, text_y;
    double a, e2;
    int nsteps = 1000;
    int i;

    /* establish the current graphics window */
    D_setup(0);

    G_get_ellipsoid_parameters(&a, &e2);
    G_begin_geodesic_distance(a, e2);

    D_use_color(line_color);

    G_shortest_way(&lon1, &lon2);

    if (lon1 != lon2) {
	G_begin_geodesic_equation(lon1, lat1, lon2, lat2);

	D_begin();

	for (i = 0; i <= nsteps; i++) {
	    double lon = lon1 + (lon2 - lon1) * i / nsteps;
	    double lat = G_geodesic_lat_from_lon(lon);

	    if (i == 0)
		D_move_abs(lon, lat);
	    else
		D_cont_abs(lon, lat);
	}

	D_end();
	D_stroke();

	text_x = (lon1 + lon2) / 2;
	text_y = G_geodesic_lat_from_lon(text_x);
    }
    else {
	D_line_abs(lon1, lat1, lon2, lat2);
	text_x = (lon1 + lon2) / 2;
	text_y = (lat1 + lat2) / 2;
    }

    if (text_color != -1) {
	double t, b, l, r;
	char buf[100];

	D_text_size(10, 10);

	distance = G_geodesic_distance(lon1, lat1, lon2, lat2);
	sprintf(buf, "%.0f %s", distance / factor, unit);

	D_pos_abs(text_x, text_y);
	D_get_text_box(buf, &t, &b, &l, &r);

	if (t - D_get_u_north() > 0)
	    text_y -= t - D_get_u_north();
	if (b - D_get_u_south() < 0)
	    text_y -= b - D_get_u_south();
	if (r - D_get_u_east() > 0)
	    text_x -= r - D_get_u_east();
	if (l - D_get_u_west() < 0)
	    text_x -= l - D_get_u_west();

	D_use_color(text_color);

	D_pos_abs(text_x, text_y);
	D_text(buf);
    }
}
Пример #5
0
int bar(struct stat_list *dist_stats,	/* list of distribution statistics */
	struct Colors *colors)
{
    struct stat_node *ptr;
    int draw = YES;
    long int bar_height;	/* height, in pixels, of a histogram bar */
    CELL bar_color;		/* color/category number of a histogram bar */
    DCELL dmax, range_dmin, range_dmax, dmin, dval;
    long int max_tics;		/* maximum tics allowed on an axis */
    long int xoffset;		/* offset for x-axis */
    long int yoffset;		/* offset for y-axis */
    long int stat_start;
    long int stat_finis;
    int text_height;
    int text_width;
    long int i, j;
    long int num_cats = 0;
    long int num_stats = 0;
    long int tic_every;		/* spacing, in units of category value, of tics */

    long int tic_unit;
    double t, b, l, r;
    double tt, tb, tl, tr;
    double x_line[3];		/* for border of histogram */
    double y_line[3];
    double x_box[5];		/* for histogram bar coordinates */
    double y_box[5];
    double height, width;
    double xscale;		/* scaling factors */
    double yscale;
    char xlabel[1024];
    char ylabel[1024];
    char txt[1024];
    char tic_name[80];

    /* get coordinates of current screen window */
    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);

    /* figure scaling factors and offsets */
    num_cats = dist_stats->maxcat - dist_stats->mincat + 1;

    if (nodata) {
	num_cats++;
	dist_stats->mincat--;
    }
    xscale = ((x_line[2] - x_line[1]) / ((double)num_cats));
    yscale = ((y_line[1] - y_line[0])) / dist_stats->maxstat;
    if (num_cats >= x_line[2] - x_line[1])
	xoffset = (long int)x_line[1];
    else
	xoffset = (long int)x_line[0] + 0.5 * xscale;	/* boxes need extra space */
    yoffset = (double)(y_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;
	if (nodata)
	    max_tics--;
	i = 0;
	if (is_fp) {
	    Rast_get_fp_range_min_max(&fp_range, &range_dmin, &range_dmax);
	    if (Rast_is_d_null_value(&range_dmin) ||
		Rast_is_d_null_value(&range_dmax))
		G_fatal_error("Floating point data range is empty");

	    if ((range_dmax - range_dmin) < 1.0)
		tics[i].every = 5;
	    if ((range_dmax - range_dmin) < 110)
		tics[i].every = 20;	/* dirrty hack */
	    while ((range_dmax - range_dmin) / tics[i].every > max_tics)
		i++;
	}
	else {
	    while ((num_cats / tics[i].every) > max_tics)
		i++;
	}
	tic_every = tics[i].every;
	tic_unit = tics[i].unit;
	strcpy(tic_name, tics[i].name);
    }
    else {
	if (is_fp && !cat_ranges) {
	    Rast_get_fp_range_min_max(&fp_range, &range_dmin, &range_dmax);
	    if (Rast_is_d_null_value(&range_dmin) ||
		Rast_is_d_null_value(&range_dmax))
		G_fatal_error("Floating point data range is empty");
	}
	tic_every = 1;
	tic_unit = 1;
    }

    /* X-AXIS LOOP
     *
     * loop through category range, drawing a pie-slice 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
     *
     */
    ptr = dist_stats->ptr;
    for (i = dist_stats->mincat; i <= dist_stats->maxcat; i++) {
	if (!ptr)
	    break;
	draw = NO;
	/* figure bar color and height 
	 *
	 * the cat number determines the color, the corresponding stat,
	 * determines the bar height.  if a stat cannot be found for the
	 * cat, then it doesn't drow anything, before it used to draw the
	 * box of size 0 in black. Later when the option to provide the
	 * background color will be added , we might still draw a box in
	 * this color.
	 */
	if (nodata && i == dist_stats->mincat) {
	    if (dist_stats->null_stat == 0 && xscale > 1)
		draw = NO;
	    else {
		draw = YES;
		Rast_set_c_null_value(&bar_color, 1);
		bar_height =
		    (yoffset - yscale * (double)dist_stats->null_stat);
	    }
	}
	else if (ptr->cat == i) {	/* AH-HA!! found the stat */
	    if (ptr->stat == 0 && xscale > 1)
		draw = NO;
	    else {
		draw = YES;
		bar_color = ptr->cat;
		bar_height = (yoffset - yscale * (double)ptr->stat);
	    }
	    if (ptr->next != NULL)
		ptr = ptr->next;
	}
	else {			/* we have to look for the stat */

	    /* loop until we find it, or pass where it should be */
	    while (ptr->cat < i && ptr->next != NULL)
		ptr = ptr->next;
	    if (ptr->cat == i) {	/* AH-HA!! found the stat */
		if (ptr->stat == 0 && xscale > 1)
		    draw = NO;
		else {
		    draw = YES;
		    bar_color = ptr->cat;
		    bar_height = (yoffset - yscale * (double)ptr->stat);
		}
		if (ptr->next != NULL)
		    ptr = ptr->next;
	    }
	    else {		/* stat cannot be found */

		if (xscale > 1) {
		    draw = NO;

#ifdef notdef
		    draw = YES;
		    bar_color = D_translate_color("black");
		    bar_height = yoffset;	/* zero */
#endif
		}
		else
		    draw = NO;
	    }
	}

	/* draw the bar */
	if (draw == YES) {
	    if (xscale != 1) {
		/* draw the bar as a box */
		if (!Rast_is_c_null_value(&bar_color) && is_fp) {
		    if (cat_ranges)
			Rast_get_ith_d_cat(&cats, bar_color,
					       &dmin, &dmax);
		    else {
			dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps;
			dmax = range_dmin + (i + 1) * (range_dmax - range_dmin) / nsteps;
		    }
		    if (dmin != dmax) {
			for (j = 0; j < xscale; j++) {
			    dval = dmin + j * (dmax - dmin) / xscale;
			    D_d_color(dval, colors);
			    x_box[0] = x_box[1] =
				xoffset + ((i - dist_stats->mincat) * xscale -
					   0.5 * xscale + j);
			    x_box[2] = x_box[3] =
				xoffset + ((i - dist_stats->mincat) * xscale -
					   0.5 * xscale + j + 1);
			    y_box[0] = y_box[3] = yoffset;
			    y_box[1] = y_box[2] = bar_height;
			    D_polygon_abs(x_box, y_box, 4);
			}
		    }
		    else {	/* 1-color bar */

			D_d_color(dmin, colors);
			x_box[0] = x_box[1] =
			    xoffset + ((i - dist_stats->mincat) * xscale -
				       0.5 * xscale);
			x_box[2] = x_box[3] =
			    xoffset + ((i - dist_stats->mincat) * xscale +
				       0.5 * xscale);
			y_box[0] = y_box[3] = yoffset;
			y_box[1] = y_box[2] = bar_height;
			D_polygon_abs(x_box, y_box, 4);
		    }
		}		/* fp */
		else {		/* 1-color bar for int data or null */

		    D_color((CELL) bar_color, colors);
		    x_box[0] = x_box[1] =
			xoffset + ((i - dist_stats->mincat) * xscale -
				   0.5 * xscale);
		    x_box[2] = x_box[3] =
			xoffset + ((i - dist_stats->mincat) * xscale +
				   0.5 * xscale);
		    y_box[0] = y_box[3] = yoffset;
		    y_box[1] = y_box[2] = bar_height;
		    D_polygon_abs(x_box, y_box, 4);
		}
	    }
	    else {
		/* draw the bar as a line */
		if (is_fp) {
		    if (cat_ranges)
			Rast_get_ith_d_cat(&cats, bar_color,
					       &dmin, &dmax);
		    else {
			dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps;
			dmax = range_dmin + (i + 1) * (range_dmax - range_dmin) / nsteps;
		    }
		    D_d_color(dmin, colors);
		}
		else
		    D_color((CELL) bar_color, colors);
		x_box[0] = x_box[1] =
		    xoffset + (i - dist_stats->mincat) * xscale;
		y_box[0] = yoffset;
		y_box[1] = bar_height;
		D_line_abs(x_box[0], y_box[0], x_box[1], y_box[1]);
	    }
	}

	/* draw x-axis tic-marks and numbers */
	/* draw tick for null and for numbers at every tic step
	   except when there is null, don't draw tic for mincat+1 */

	if (((rem((long int)i, tic_every) == 0L) ||
	     ((i == dist_stats->mincat) && nodata))
	    && !(nodata && i == dist_stats->mincat + 1)) {

	    /* draw a numbered tic-mark */
	    D_use_color(color);
	    D_begin();
	    D_move_abs(xoffset + (i - dist_stats->mincat) * xscale - 0.5 * xscale,
		       b - ORIGIN_Y * (b - t));
	    D_cont_rel(0, BIG_TIC * (b - t));
	    D_end();
	    D_stroke();

	    if (nodata && i == dist_stats->mincat)
		sprintf(txt, "null");
	    else if (is_fp) {
		dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps;
		if ((tic_every * (range_dmax - range_dmin) / nsteps) < 1.0)
		    sprintf(txt, "%.2f", dmin / (double)tic_unit);
		else
		    sprintf(txt, "%d", (int)(dmin / (double)tic_unit));
	    }
	    else
		sprintf(txt, "%d", (int)(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 ((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 + (i - dist_stats->mincat) * xscale - 0.5 * xscale - (tr - tl) / 2,
		      b - XNUMS_Y * (b - t));
	    D_text(txt);
	}
	else if (rem(i, tic_unit) == 0.0) {
	    /* draw a tic-mark */
	    D_use_color(color);
	    D_begin();
	    D_move_abs(xoffset + (i - dist_stats->mincat) * xscale - 0.5 * xscale,
		       b - ORIGIN_Y * (b - t));
	    D_cont_rel(0, SMALL_TIC * (b - t));
	    D_end();
	    D_stroke();
	}
    }

    /* draw the x-axis label */
    if (tic_unit != 1)
	sprintf(xlabel, "X-AXIS: Cell Values %s", tic_name);
    else
	sprintf(xlabel, "X-AXIS: Cell Values");
    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH;
    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(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.
     */

    max_tics = (long)((y_line[1] - y_line[0]) / YTIC_DIST);

    if (dist_stats->maxstat == dist_stats->minstat)
	dist_stats->minstat = 0;	/* LOOKS FUNNY TO ME */
    num_stats = dist_stats->maxstat - dist_stats->minstat;
    i = 0;
    while ((num_stats / tics[i].every) > max_tics)
	i++;
    tic_every = tics[i].every;
    tic_unit = tics[i].unit;
    strcpy(tic_name, tics[i].name);

    stat_start = tic_unit * ((long)(dist_stats->minstat / tic_unit));
    stat_finis = tic_unit * ((long)(dist_stats->maxstat / tic_unit));

    /* Y-AXIS LOOP
     *
     */
    for (i = stat_start; i <= stat_finis; i += tic_unit) {
	if (rem(i, tic_every) == (float)0) {
	    /* draw a tic-mark */
	    D_begin();
	    D_move_abs(x_line[0], yoffset - yscale * i);
	    D_cont_rel((-(r - l) * BIG_TIC), 0);
	    D_end();
	    D_stroke();

	    /* draw a tic-mark number */
	    sprintf(txt, "%d", (int)(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 + 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);
	    D_cont_rel(-(r - l) * SMALL_TIC, 0);
	    D_end();
	    D_stroke();
	}
    }

    /* draw the y-axis label */
    if (tic_unit != 1) {
	if (type == COUNT)
	    sprintf(ylabel, "Y-AXIS: Number of cells %s", tic_name);
	else
	    sprintf(ylabel, "Y-AXIS: Area %s sq. meters", tic_name);
    }
    else {
	if (type == COUNT)
	    sprintf(ylabel, "Y-AXIS: Number of cells");
	else
	    sprintf(ylabel, "Y-AXIS: Area");
    }

    text_height = (b - t) * TEXT_HEIGHT;
    text_width = (r - l) * TEXT_WIDTH;
    D_text_size(text_width, text_height);
    D_get_text_box(ylabel, &tt, &tb, &tl, &tr);
    D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2,
	      b - LABEL_2 * (b - t));
    D_use_color(color);
    D_text(ylabel);

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

    return 0;
}
Пример #6
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);
}
Пример #7
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;
}
Пример #8
0
int draw_slice(struct Colors *colors, int fill_flag, DCELL fill_color1, DCELL fill_color2, int txt_color, double cx, double cy, double r,	/* in normalized coords. */
	       double a1, double a2	/* in degrees */
    )
{
    double tt, tb, tr, tl;
    int height, width;
    double yoffset, xoffset;
    double x[1000], y[1000];
    int lx, ly;
    int i = 1;
    char txt[512];
    double arc, arc_incr = 0.01;
    DCELL fill_color;

    D_get_src(&tt, &tb, &tl, &tr);

    height = tb - tt;
    width = tr - tl;
    yoffset = tb;
    xoffset = tl;

    while (a2 / arc_incr > 998)
	arc_incr *= 2;

    x[0] = (xoffset + cx * width);
    y[0] = (yoffset - cy * height);

    arc = a1;
    if (fill_flag && fill_color1 != fill_color2) {
	i = 1;
	while (arc <= (a1 + a2)) {
	    fill_color = fill_color1 + (arc - a1) *
		(fill_color2 - fill_color1) / a2;
	    x[i] = x[0] + r * (width) * cos(arc / 57.296);
	    y[i] = y[0] - r * (height) * sin(arc / 57.296);
	    if (i == 2) {
		D_d_color(fill_color, colors);
		D_polygon_abs(x + i - 2, y + i - 2, 3);
		x[i - 1] = x[i];
		y[i - 1] = y[i];
	    }
	    else
		i++;
	    arc = arc + arc_incr;
	}
    }
    else {
	i = 1;
	while (arc <= (a1 + a2)) {
	    x[i] = x[0] + r * (width) * cos(arc / 57.296);
	    y[i] = y[0] - r * (height) * sin(arc / 57.296);
	    i++;
	    arc = arc + arc_incr;
	}

	if (!fill_flag) {
	    D_use_color(txt_color);
	    D_polyline_abs(x, y, i);
	}
	else {
	    D_d_color(fill_color1, colors);
	    D_polygon_abs(x, y, i);
	}
    }

    if (a2 > 15.0) {
	/* draw a label */
	arc = a1 + a2 / 2;
	sprintf(txt, "%2.0f%s", (a2 / 360.0) * 100.0, percent);
	D_get_text_box(txt, &tt, &tb, &tl, &tr);
	lx = x[0] + (r + 0.03) * (width) * cos(arc / 57.296) - (tr - tl) / 2;
	ly = y[0] - (r + 0.03) * (height) * sin(arc / 57.296) + (tb - tt) / 2;
	D_pos_abs(lx, ly);
	D_use_color(txt_color);
	D_text(txt);
    }

    return 0;
}
Пример #9
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);
}
Пример #10
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);
}
Пример #11
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;
}