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; }
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); }
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; }
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; }
static void symbol(const SYMBOL *Symb, double x0, double y0, const RGBA_Color *fill_color, const RGBA_Color *line_color, const RGBA_Color *string_color) { int i, j, k; const SYMBPART *part; const SYMBCHAIN *chain; double xp, yp; double *x, *y; double sx = D_get_d_to_u_xconv(); double sy = D_get_d_to_u_yconv(); G_debug(2, "D_symbol(): %d parts", Symb->count); for (i = 0; i < Symb->count; i++) { part = Symb->part[i]; switch (part->type) { case S_POLYGON: /* draw background fills */ if ((part->fcolor.color == S_COL_DEFAULT && fill_color->a != RGBA_COLOR_NONE) || part->fcolor.color == S_COL_DEFINED) { if (part->fcolor.color == S_COL_DEFAULT) D_RGB_color(fill_color->r, fill_color->g, fill_color->b); else D_RGB_color(part->fcolor.r, part->fcolor.g, part->fcolor.b); for (j = 0; j < part->count; j++) { /* for each component polygon */ chain = part->chain[j]; x = G_malloc(sizeof(double) * chain->scount); y = G_malloc(sizeof(double) * chain->scount); for (k = 0; k < chain->scount; k++) { x[k] = x0 + sx * chain->sx[k]; y[k] = y0 - sy * chain->sy[k]; } D_polygon_abs(x, y, chain->scount); G_free(x); G_free(y); } } /* again, to draw the lines */ if ((part->color.color == S_COL_DEFAULT && line_color->a != RGBA_COLOR_NONE) || part->color.color == S_COL_DEFINED) { if (part->color.color == S_COL_DEFAULT) D_RGB_color(line_color->r, line_color->g, line_color->b); else D_RGB_color(part->color.r, part->color.g, part->color.b); for (j = 0; j < part->count; j++) { chain = part->chain[j]; D_begin(); for (k = 0; k < chain->scount; k++) { xp = x0 + sx * chain->sx[k]; yp = y0 - sy * chain->sy[k]; if (k == 0) D_move_abs(xp, yp); else D_cont_abs(xp, yp); } D_end(); D_stroke(); } } break; case S_STRING: if (part->color.color == S_COL_NONE) break; else if (part->color.color == S_COL_DEFAULT && string_color->a != RGBA_COLOR_NONE) D_RGB_color(string_color->r, string_color->g, string_color->b); else D_RGB_color(part->color.r, part->color.g, part->color.b); chain = part->chain[0]; D_begin(); for (j = 0; j < chain->scount; j++) { xp = x0 + sx * chain->sx[j]; yp = y0 - sy * chain->sy[j]; if (j == 0) D_move_abs(xp, yp); else D_cont_abs(xp, yp); } D_end(); D_stroke(); break; } /* switch */ } /* for loop */ }
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; }
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; }