예제 #1
0
int display(struct Map_info *Map, struct line_pnts *Points,
	    const struct color_rgb *color, int first, int last, int be_bold)
{
    int from, to;

    D_RGB_color(color->r, color->g, color->b);

    if (first)
	from = 0;
    else
	from = 1;
    if (last)
	to = Points->n_points;
    else
	to = Points->n_points - 1;

    if (be_bold)
	D_line_width(2);

    D_polyline_abs(&Points->x[from], &Points->y[from], to - from);

    if (be_bold)
	D_line_width(0);

    return 0;
}
예제 #2
0
파일: pie.c 프로젝트: AsherBond/MondocosmOS
int
pie(double cx, double cy, int size, double *val, int ncols, COLOR * ocolor,
    COLOR * colors)
{
    int i, j, n;
    double a, end_ang, ang, tot_sum, sum, step, r;
    double x, y;
    struct line_pnts *Points;

    G_debug(4, "pie(): cx = %f cy = %f", cx, cy);

    Points = Vect_new_line_struct();

    /* Calc sum */
    tot_sum = 0;
    for (i = 0; i < ncols; i++)
	tot_sum += val[i];

    step = PI / 180;
    r = (D_d_to_u_col(2) - D_d_to_u_col(1)) * size / 2;	/* do it better */
    /* Draw polygon for each value */
    sum = 0;
    ang = 0;
    for (i = 0; i < ncols; i++) {
	sum += val[i];
	end_ang = 2 * PI * sum / tot_sum;
	Vect_reset_line(Points);

	if (val[0] != tot_sum)	/* all in one slice, don't draw line to center */
	    Vect_append_point(Points, cx, cy, 0);

	n = (int)ceil((end_ang - ang) / step);
	for (j = 0, a = ang; j <= n; j++, a += step) {
	    if (a > end_ang)
		a = end_ang;
	    x = cx + r * cos(a);
	    y = cy + r * sin(a);
	    Vect_append_point(Points, x, y, 0);
	}
	ang = end_ang;

	if (val[0] != tot_sum)
	    Vect_append_point(Points, cx, cy, 0);

	if (!colors[i].none) {
	    D_RGB_color(colors[i].r, colors[i].g, colors[i].b);
	    D_polygon_abs(Points->x, Points->y, Points->n_points);
	}

	D_RGB_color(ocolor->r, ocolor->g, ocolor->b);
	D_polyline_abs(Points->x, Points->y, Points->n_points);
    }

    Vect_destroy_line_struct(Points);

    return 0;
}
예제 #3
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);
}
예제 #4
0
/* *************************************************************** */
int plot1(struct Map_info *Map, int type, int area, struct cat_list *Clist,
	  const struct color_rgb *color, const struct color_rgb *fcolor,
	  int chcat, SYMBOL * Symb, int size, int id_flag,
	  int table_colors_flag, int cats_color_flag, char *rgb_column,
	  int default_width, char *width_column, double width_scale)
{
    int i, ltype, nlines = 0, line, cat = -1;
    double *x, *y;
    struct line_pnts *Points, *PPoints;
    struct line_cats *Cats;
    double msize;
    int x0, y0;

    struct field_info *fi = NULL;
    dbDriver *driver = NULL;
    dbCatValArray cvarr_rgb, cvarr_width;
    dbCatVal *cv_rgb = NULL, *cv_width = NULL;
    int nrec_rgb = 0, nrec_width = 0;

    int open_db;
    int custom_rgb = FALSE;
    char colorstring[12];	/* RRR:GGG:BBB */
    int red, grn, blu;
    RGBA_Color *line_color, *fill_color, *primary_color;
    unsigned char which;
    int width;

    line_color = G_malloc(sizeof(RGBA_Color));
    fill_color = G_malloc(sizeof(RGBA_Color));
    primary_color = G_malloc(sizeof(RGBA_Color));

    primary_color->a = RGBA_COLOR_OPAQUE;

    /* change function prototype to pass RGBA_Color instead of color_rgb? */
    if (color) {
	line_color->r = color->r;
	line_color->g = color->g;
	line_color->b = color->b;
	line_color->a = RGBA_COLOR_OPAQUE;
    }
    else
	line_color->a = RGBA_COLOR_NONE;

    if (fcolor) {
	fill_color->r = fcolor->r;
	fill_color->g = fcolor->g;
	fill_color->b = fcolor->b;
	fill_color->a = RGBA_COLOR_OPAQUE;
    }
    else
	fill_color->a = RGBA_COLOR_NONE;


    msize = size * (D_d_to_u_col(2.0) - D_d_to_u_col(1.0));	/* do it better */

    Points = Vect_new_line_struct();
    PPoints = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    open_db = table_colors_flag || width_column;

    if (open_db) {
	fi = Vect_get_field(Map, (Clist->field > 0 ? Clist->field : 1));
	if (fi == NULL) {
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  (Clist->field > 0 ? Clist->field : 1));
	}

	driver = db_start_driver_open_database(fi->driver, fi->database);
	if (driver == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  fi->database, fi->driver);
    }

    if (table_colors_flag) {
	/* for reading RRR:GGG:BBB color strings from table */

	if (rgb_column == NULL || *rgb_column == '\0')
	    G_fatal_error(_("Color definition column not specified"));

	db_CatValArray_init(&cvarr_rgb);

	nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key,
					 rgb_column, NULL, &cvarr_rgb);

	G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb);

	if (cvarr_rgb.ctype != DB_C_TYPE_STRING)
	    G_fatal_error(_("Color definition column (%s) not a string. "
			    "Column must be of form RRR:GGG:BBB where RGB values range 0-255."),
			  rgb_column);

	if (nrec_rgb < 0)
	    G_fatal_error(_("Cannot select data (%s) from table"),
			  rgb_column);

	G_debug(2, "\n%d records selected from table", nrec_rgb);

	for (i = 0; i < cvarr_rgb.n_values; i++) {
	    G_debug(4, "cat = %d  %s = %s", cvarr_rgb.value[i].cat,
		    rgb_column, db_get_string(cvarr_rgb.value[i].val.s));
	}
    }

    if (width_column) {
	if (*width_column == '\0')
	    G_fatal_error(_("Line width column not specified."));

	db_CatValArray_init(&cvarr_width);

	nrec_width = db_select_CatValArray(driver, fi->table, fi->key,
					   width_column, NULL, &cvarr_width);

	G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width);

	if (cvarr_width.ctype != DB_C_TYPE_INT &&
	    cvarr_width.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Line width column (%s) not a number."),
			  width_column);

	if (nrec_width < 0)
	    G_fatal_error(_("Cannot select data (%s) from table"),
			  width_column);

	G_debug(2, "\n%d records selected from table", nrec_width);

	for (i = 0; i < cvarr_width.n_values; i++) {
	    G_debug(4, "cat = %d  %s = %d", cvarr_width.value[i].cat,
		    width_column,
		    (cvarr_width.ctype ==
		     DB_C_TYPE_INT ? cvarr_width.value[i].val.
		     i : (int)cvarr_width.value[i].val.d));
	}
    }

    if (open_db)
	db_close_database_shutdown_driver(driver);

    Vect_rewind(Map);

    /* Is it necessary to reset line/label color in each loop ? */

    if (color && !table_colors_flag && !cats_color_flag)
	D_RGB_color(color->r, color->g, color->b);

    if (Vect_level(Map) >= 2)
	nlines = Vect_get_num_lines(Map);

    line = 0;
    while (1) {
	if (Vect_level(Map) >= 2) {
	    line++;
	    if (line > nlines)
		return 0;
	    if (!Vect_line_alive(Map, line))
		continue;
	    ltype = Vect_read_line(Map, Points, Cats, line);
	}
	else {
	    ltype = Vect_read_next_line(Map, Points, Cats);
	    switch (ltype) {
	    case -1:
		fprintf(stderr, _("\nERROR: vector map - can't read\n"));
		return -1;
	    case -2:		/* EOF */
		return 0;
	    }
	}

	if (!(type & ltype))
	    continue;

	if (chcat) {
	    int found = 0;

	    if (id_flag) {	/* use line id */
		if (!(Vect_cat_in_cat_list(line, Clist)))
		    continue;
	    }
	    else {
		for (i = 0; i < Cats->n_cats; i++) {
		    if (Cats->field[i] == Clist->field &&
			Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
			found = 1;
			break;
		    }
		}
		if (!found)
		    continue;
	    }
	}
	else if (Clist->field > 0) {
	    int found = 0;

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == Clist->field) {
		    found = 1;
		    break;
		}
	    }
	    /* lines with no category will be displayed */
	    if (Cats->n_cats > 0 && !found)
		continue;
	}


	if (table_colors_flag) {

	    /* only first category */
	    cat = Vect_get_line_cat(Map, line,
				    (Clist->field > 0 ? Clist->field :
				     (Cats->n_cats >
				      0 ? Cats->field[0] : 1)));

	    if (cat >= 0) {
		G_debug(3, "display element %d, cat %d", line, cat);

		/* Read RGB colors from db for current area # */
		if (db_CatValArray_get_value(&cvarr_rgb, cat, &cv_rgb) !=
		    DB_OK) {
		    custom_rgb = FALSE;
		}
		else {
		    sprintf(colorstring, "%s", db_get_string(cv_rgb->val.s));

		    if (*colorstring != '\0') {
			G_debug(3, "element %d: colorstring: %s", line,
				colorstring);

			if (G_str_to_color(colorstring, &red, &grn, &blu) ==
			    1) {
			    custom_rgb = TRUE;
			    G_debug(3, "element:%d  cat %d r:%d g:%d b:%d",
				    line, cat, red, grn, blu);
			}
			else {
			    custom_rgb = FALSE;
			    G_warning(_("Error in color definition column (%s), element %d "
				       "with cat %d: colorstring [%s]"),
				      rgb_column, line, cat, colorstring);
			}
		    }
		    else {
			custom_rgb = FALSE;
			G_warning(_("Error in color definition column (%s), element %d with cat %d"),
				  rgb_column, line, cat);
		    }
		}
	    }			/* end if cat */
	    else {
		custom_rgb = FALSE;
	    }
	}			/* end if table_colors_flag */


	/* random colors */
	if (cats_color_flag) {
	    custom_rgb = FALSE;
	    if (Clist->field > 0) {
		cat = Vect_get_line_cat(Map, line, Clist->field);
		if (cat >= 0) {
		    G_debug(3, "display element %d, cat %d", line, cat);
		    /* fetch color number from category */
		    which = (cat % palette_ncolors);
		    G_debug(3, "cat:%d which color:%d r:%d g:%d b:%d", cat,
			    which, palette[which].R, palette[which].G,
			    palette[which].B);

		    custom_rgb = TRUE;
		    red = palette[which].R;
		    grn = palette[which].G;
		    blu = palette[which].B;
		}
	    }
	    else if (Cats->n_cats > 0) {
		/* fetch color number from layer */
		which = (Cats->field[0] % palette_ncolors);
		G_debug(3, "layer:%d which color:%d r:%d g:%d b:%d",
			Cats->field[0], which, palette[which].R,
			palette[which].G, palette[which].B);

		custom_rgb = TRUE;
		red = palette[which].R;
		grn = palette[which].G;
		blu = palette[which].B;
	    }
	}


	if (nrec_width) {

	    /* only first category */
	    cat = Vect_get_line_cat(Map, line,
				    (Clist->field > 0 ? Clist->field :
				     (Cats->n_cats >
				      0 ? Cats->field[0] : 1)));

	    if (cat >= 0) {
		G_debug(3, "display element %d, cat %d", line, cat);

		/* Read line width from db for current area # */

		if (db_CatValArray_get_value(&cvarr_width, cat, &cv_width) !=
		    DB_OK) {
		    width = default_width;
		}
		else {
		    width =
			width_scale * (cvarr_width.ctype ==
				       DB_C_TYPE_INT ? cv_width->val.
				       i : (int)cv_width->val.d);
		    if (width < 0) {
			G_warning(_("Error in line width column (%s), element %d "
				   "with cat %d: line width [%d]"),
				  width_column, line, cat, width);
			width = default_width;
		    }
		}
	    }			/* end if cat */
	    else {
		width = default_width;
	    }

	    D_line_width(width);
	}			/* end if nrec_width */


	/* enough of the prep work, lets start plotting stuff */
	x = Points->x;
	y = Points->y;

	if ((ltype & GV_POINTS) && Symb != NULL) {
	    if (!(color || fcolor || custom_rgb))
		continue;

	    x0 = D_u_to_d_col(x[0]);
	    y0 = D_u_to_d_row(y[0]);

	    /* skip if the point is outside of the display window */
	    /*      xy<0 tests make it go ever-so-slightly faster */
	    if (x0 < 0 || y0 < 0 ||
		x0 > D_get_d_east() || x0 < D_get_d_west() ||
		y0 > D_get_d_south() || y0 < D_get_d_north())
		continue;

	    /* use random or RGB column color if given, otherwise reset */
	    /* centroids always use default color to stand out from underlying area */
	    if (custom_rgb && (ltype != GV_CENTROID)) {
		primary_color->r = (unsigned char)red;
		primary_color->g = (unsigned char)grn;
		primary_color->b = (unsigned char)blu;
		D_symbol2(Symb, x0, y0, primary_color, line_color);
	    }
	    else
		D_symbol(Symb, x0, y0, line_color, fill_color);


	}
	else if (color || custom_rgb) {
	    if (!table_colors_flag && !cats_color_flag)
		D_RGB_color(color->r, color->g, color->b);
	    else {
		if (custom_rgb)
		    D_RGB_color((unsigned char)red, (unsigned char)grn,
				(unsigned char)blu);
		else
		    D_RGB_color(color->r, color->g, color->b);
	    }

	    /* Plot the lines */
	    if (Points->n_points == 1)	/* line with one coor */
		D_polydots_abs(x, y, Points->n_points);
	    else		/*use different user defined render methods */
		D_polyline_abs(x, y, Points->n_points);
	}
    }

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;			/* not reached */
}
예제 #5
0
파일: bar.c 프로젝트: GRASS-GIS/grass-ci
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 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;
}
예제 #7
0
int
bar(double cx, double cy, int size, double scale, double *val, int ncols,
    COLOR * ocolor, COLOR * colors, int y_center, double *max_reference,
    int do3d)
{
    int i;
    double max;
    double x0, y0, x1, y1, dx, dy;
    double bw;			/* bar width */
    double pixel;		/* pixel size */
    struct line_pnts *Points, *max_Points;

    G_debug(4, "bar(): cx = %f cy = %f", cx, cy);

    Points = Vect_new_line_struct();
    max_Points = Vect_new_line_struct();

    pixel = D_d_to_u_col(2) - D_d_to_u_col(1);	/* do it better */

    /* Bottom (y0) */
    max = 0;
    for (i = 0; i < ncols; i++) {
	if (val[i] > max)
	    max = val[i];
    }

    /* debug */
    /* printf("%f \n", max_reference); */

    if (y_center == 0)
	/* draw the columns with the bottom at the y value of the point  */
	y0 = cy;
    else
	/* center the columns around the y value of the point */
	y0 = cy - scale * max * pixel / 2;

    /* Left (x0) */
    x0 = cx - size * pixel / 2;

    bw = size * pixel / ncols;
    dx = bw / 5.0;
    dy = dx * 1.5;

    if (max_reference) {
	/* Draw polygon outlining max value in dataset with no fill color */
	for (i = 0; i < ncols; i++) {
	    Vect_reset_line(max_Points);
	    Vect_append_point(max_Points, x0 + i * bw, y0, 0);
	    Vect_append_point(max_Points, x0 + (i + 1) * bw, y0, 0);
	    Vect_append_point(max_Points, x0 + (i + 1) * bw,
			      y0 + scale * max_reference[i] * pixel, 0);
	    Vect_append_point(max_Points, x0 + i * bw,
			      y0 + scale * max_reference[i] * pixel, 0);
	    Vect_append_point(max_Points, x0 + i * bw, y0, 0);

	    /* the outline color : default is black */
	    D_RGB_color(ocolor->r, ocolor->g, ocolor->b);
	    D_polyline_abs(max_Points->x, max_Points->y, max_Points->n_points);
	}
    }

    /* Draw polygon for each value */
    for (i = 0; i < ncols; i++) {
	Vect_reset_line(Points);
	Vect_append_point(Points, x0 + i * bw, y0, 0);
	Vect_append_point(Points, x0 + (i + 1) * bw, y0, 0);
	Vect_append_point(Points, x0 + (i + 1) * bw,
			  y0 + scale * val[i] * pixel, 0);
	Vect_append_point(Points, x0 + i * bw, y0 + scale * val[i] * pixel,
			  0);
	Vect_append_point(Points, x0 + i * bw, y0, 0);

	if (!colors[i].none) {
	    D_RGB_color(colors[i].r, colors[i].g, colors[i].b);
	    D_polygon_abs(Points->x, Points->y, Points->n_points);
	}

	D_RGB_color(ocolor->r, ocolor->g, ocolor->b);
	D_polyline_abs(Points->x, Points->y, Points->n_points);
	
	if (do3d) {
	    /* up */
	    Vect_reset_line(Points);
	    y1 = y0 + scale * val[i] * pixel;
	    Vect_append_point(Points, x0 + i * bw, y1, 0);
	    Vect_append_point(Points, x0 + i * bw + dx, y1 + dy, 0);
	    Vect_append_point(Points, x0 + (i + 1) * bw + dx, y1 + dy, 0);
	    Vect_append_point(Points, x0 + (i + 1) * bw, y1, 0);
	    Vect_append_point(Points, x0 + i * bw, y1, 0);

	    if (!colors[i].none) {
		D_RGB_color(colors[i].r, colors[i].g, colors[i].b);
		D_polygon_abs(Points->x, Points->y, Points->n_points);
	    }

	    D_RGB_color(ocolor->r, ocolor->g, ocolor->b);
	    /* do not draw the same line twice */
	    Points->n_points = 4;
	    D_polyline_abs(Points->x, Points->y, Points->n_points);

	    /* right */
	    Vect_reset_line(Points);
	    x1 = x0 + (i + 1) * bw;
	    Vect_append_point(Points, x1 + dx + 0.5 * pixel, y1 + dy, 0);
	    Vect_append_point(Points, x1 + dx + 0.5 * pixel, y0 + dy, 0);
	    Vect_append_point(Points, x1, y0, 0);
	    Vect_append_point(Points, x1, y1, 0);
	    Vect_append_point(Points, x1 + dx + 0.5 * pixel, y1 + dy, 0);

	    if (!colors[i].none && val[i] > 0) {
		D_RGB_color(colors[i].r, colors[i].g, colors[i].b);
		D_polygon_abs(Points->x, Points->y, Points->n_points);
	    }

	    D_RGB_color(ocolor->r, ocolor->g, ocolor->b);
	    /* do not draw the same line twice */
	    Points->n_points = 3;
	    D_polyline_abs(Points->x, Points->y, Points->n_points);
	}
    }

    /* tidy up */
    Vect_destroy_line_struct(Points);
    Vect_destroy_line_struct(max_Points);

    return 0;
}
예제 #8
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);
}
예제 #9
0
파일: area.c 프로젝트: caomw/grass
int display_area(struct Map_info *Map, struct cat_list *Clist, const struct Cell_head *window,
		 const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat,
		 int id_flag, int cats_color_flag, 
		 int default_width, double width_scale,
		 struct Colors *zcolors,
		 dbCatValArray *cvarr_rgb, struct Colors *colors,
		 dbCatValArray *cvarr_width, int nrec_width)
{
    int num, area, isle, n_isles, n_points;
    double xl, yl;
    struct line_pnts *Points, * APoints, **IPoints;
    struct line_cats *Cats;
    int n_ipoints_alloc;
    int cat, centroid;
    int red, grn, blu;

    int i, custom_rgb, found;
    int width;
    struct bound_box box;
    
    if (Vect_level(Map) < 2) {
	G_warning(_("Unable to display areas, topology not available. "
		    "Please try to rebuild topology using "
		    "v.build or v.build.all."));
	return 1;
    }

    G_debug(1, "display areas:");
    
    centroid = 0;
    Points = Vect_new_line_struct();
    APoints = Vect_new_line_struct();
    n_ipoints_alloc = 10;
    IPoints = (struct line_pnts **)G_malloc(n_ipoints_alloc * sizeof(struct line_pnts *));
    for (i = 0; i < n_ipoints_alloc; i++) {
	IPoints[i] = Vect_new_line_struct();
    }
    Cats = Vect_new_cats_struct();
    
    num = Vect_get_num_areas(Map);
    G_debug(2, "\tn_areas = %d", num);

    for (area = 1; area <= num; area++) {
	G_debug(3, "\tarea = %d", area);

	if (!Vect_area_alive(Map, area))
	    continue;

	centroid = Vect_get_area_centroid(Map, area);
	if (!centroid) {
	    continue;
	}

	/* Check box */
	Vect_get_area_box(Map, area, &box);
	if (box.N < window->south || box.S > window->north ||
	    box.E < window->west || box.W > window->east) {
	    if (window->proj != PROJECTION_LL)
		continue;
	    else { /* out of bounds for -180 to 180, try 0 to 360 as well */
		if (box.N < window->south || box.S > window->north)
		    continue;
		if (box.E + 360 < window->west || box.W + 360 > window->east)
		    continue;
	    }
	}

	custom_rgb = FALSE;
		
	found = FALSE;
	if (chcat) {		
	    if (id_flag) {
		if (!(Vect_cat_in_cat_list(area, Clist)))
		    continue;
	    }
	    else {
		G_debug(3, "centroid = %d", centroid);
		if (centroid < 1)
		    continue;
		Vect_read_line(Map, Points, Cats, centroid);

		for (i = 0; i < Cats->n_cats; i++) {
		    G_debug(3, "  centroid = %d, field = %d, cat = %d",
			    centroid, Cats->field[i], Cats->cat[i]);

		    if (Cats->field[i] == Clist->field &&
			Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
			found = TRUE;
			break;
		    }
		}
		
		if (!found)
		    continue;
	    }
	}
	else if (Clist->field > 0) {
	    found = FALSE;
	    G_debug(3, "\tcentroid = %d", centroid);
	    if (centroid < 1)
		continue;
	    Vect_read_line(Map, NULL, Cats, centroid);

	    for (i = 0; i < Cats->n_cats; i++) {
		G_debug(3, "\tcentroid = %d, field = %d, cat = %d", centroid,
			Cats->field[i], Cats->cat[i]);
		if (Cats->field[i] == Clist->field) {
		    found = TRUE;
		    break;
		}
	    }
	    
	    /* lines with no category will be displayed */
	    if (Cats->n_cats > 0 && !found)
		continue;
	}

	/* fill */
	Vect_get_area_points(Map, area, APoints);
	G_debug(3, "\tn_points = %d", APoints->n_points);
	if (APoints->n_points < 3) {
	    G_warning(_("Invalid area %d skipped (not enough points)"), area);
	    continue;
	}
	Vect_reset_line(Points);
	Vect_append_points(Points, APoints, GV_FORWARD);

	n_points = Points->n_points;
	xl = Points->x[n_points - 1];
	yl = Points->y[n_points - 1];
	n_isles = Vect_get_area_num_isles(Map, area);
	if (n_isles >= n_ipoints_alloc) {
	    IPoints = (struct line_pnts **)G_realloc(IPoints, (n_isles + 10) * sizeof(struct line_pnts *));
	    for (i = n_ipoints_alloc; i < n_isles + 10; i++) {
		IPoints[i] = Vect_new_line_struct();
	    }
	    n_ipoints_alloc = n_isles + 10;
	}
	for (i = 0; i < n_isles; i++) {
	    isle = Vect_get_area_isle(Map, area, i);
	    Vect_get_isle_points(Map, isle, IPoints[i]);
	    Vect_append_points(Points, IPoints[i], GV_FORWARD);
	    Vect_append_point(Points, xl, yl, 0.0);	/* ??? */
	}

	cat = Vect_get_area_cat(Map, area,
				(Clist->field > 0 ? Clist->field :
				 (Cats->n_cats > 0 ? Cats->field[0] : 1)));

	if (!centroid && cat == -1) {
	    continue;
	}

	/* z height colors */
	if (zcolors) {
	    if (Rast_get_d_color(&Points->z[0], &red, &grn, &blu, zcolors) == 1)
		custom_rgb = TRUE;
	    else
		custom_rgb = FALSE;
	}

        /* custom colors */
	if (colors || cvarr_rgb) {
	    custom_rgb = get_table_color(cat, area, colors, cvarr_rgb,
					 &red, &grn, &blu);
	}
	
	/* random colors */
	if (cats_color_flag) {
	    custom_rgb = get_cat_color(area, Cats, Clist,
				       &red, &grn, &blu);
	}
	
	/* line width */
	if (nrec_width) {
	    width = (int) get_property(cat, area, cvarr_width,
				       (double) width_scale,
				       (double) default_width);
	    
	    D_line_width(width);
	}
	
	if (fcolor || zcolors) {
	    if (!cvarr_rgb && !cats_color_flag && !zcolors && !colors) {
		D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
		D_polygon_abs(Points->x, Points->y, Points->n_points);
	    }
	    else {
		if (custom_rgb) {
		    D_RGB_color((unsigned char)red, (unsigned char)grn,
				(unsigned char)blu);
		}
		else {
		    D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
		}
		if (cat >= 0) {
		    D_polygon_abs(Points->x, Points->y, Points->n_points);
		}
	    }
	}

	/* boundary */
	if (bcolor) {
	    if (custom_rgb) {
		D_RGB_color((unsigned char)red, (unsigned char)grn,
			    (unsigned char)blu);
	    }
	    else {
		D_RGB_color(bcolor->r, bcolor->g, bcolor->b);
	    }
	    /* use different user defined render methods */
	    D_polyline_abs(APoints->x, APoints->y, APoints->n_points);
	    for (i = 0; i < n_isles; i++) {
		/* use different user defined render methods */
		D_polyline_abs(IPoints[i]->x, IPoints[i]->y, IPoints[i]->n_points);
	    }
	}
    }

    if ((colors || cvarr_rgb) && get_num_color_rules_skipped() > 0)
        G_warning(_n("%d invalid color rule for areas skipped", 
                "%d invalid color rules for areas skipped", 
                get_num_color_rules_skipped()), 
                get_num_color_rules_skipped());

    Vect_destroy_line_struct(Points);
    Vect_destroy_line_struct(APoints);
    for (i = 0; i < n_ipoints_alloc; i++) {
	Vect_destroy_line_struct(IPoints[i]);
    }
    G_free(IPoints);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
예제 #10
0
int draw_line(int ltype, int line,
              const struct line_pnts *Points, const struct line_cats *Cats,
              int chcat, double size, int default_width,
              const struct cat_list *Clist, SYMBOL * Symb,
              RGBA_Color * primary_color,
              int *n_points, int *n_lines, int *n_centroids,
              int *n_boundaries, int *n_faces, RGBA_Color *secondary_color)
{
    double var_size, rotation;
    int i;
    double x0, y0;
    double *x, *y;
    int found, cat;

    rotation = 0.0;
    var_size = size;
    cat = -1;

    if (!ltype)
        return 0;

    if (Points->n_points == 0)
        return 0;

    found = FALSE;
    if (chcat) {
        for (i = 0; i < Cats->n_cats; i++) {
            if (Cats->field[i] == Clist->field &&
                Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
                found = TRUE;
                break;
            }
        }
        if (!found)
            return 0;
    }
    else if (Clist->field > 0) {
        for (i = 0; i < Cats->n_cats; i++) {
            if (Cats->field[i] == Clist->field) {
                found = TRUE;
                break;
            }
        }
        /* lines with no category will be displayed */
        if (Cats->n_cats > 0 && !found)
            return 0;
    }

    G_debug(3, "\tdisplay feature %d, cat %d", line, cat);


    /* enough of the prep work, lets start plotting stuff */
    x = Points->x;
    y = Points->y;

    if ((ltype & GV_POINTS)) {
        x0 = x[0];
        y0 = y[0];

        /* skip if the point is outside of the display window */
        /* xy < 0 tests make it go ever-so-slightly faster */
        if (x0 > D_get_u_east() || x0 < D_get_u_west() ||
            y0 < D_get_u_south() || y0 > D_get_u_north())
            return 0;

        D_line_width(default_width);
        D_symbol2(Symb, x0, y0, primary_color, secondary_color);
    }
    else {
        /* Plot the lines */
        D_line_width(default_width);
        D_RGB_color(primary_color->r, primary_color->g, primary_color->b);
        if (Points->n_points == 1)      /* line with one coor */
            D_polydots_abs(x, y, Points->n_points);
        else                    /* use different user defined render methods */
            D_polyline_abs(x, y, Points->n_points);
    }

    switch (ltype) {
    case GV_POINT:
        (*n_points)++;
        break;
    case GV_LINE:
        (*n_lines)++;
        break;
    case GV_CENTROID:
        (*n_centroids)++;
        break;
    case GV_BOUNDARY:
        (*n_boundaries)++;
        break;
    case GV_FACE:
        (*n_faces)++;
        break;
    default:
        break;
    }

    return 1;
}