int draw_scale(char *save, int toptext, int size) { double meters; double line_len; int incr; int x_pos, y_pos; int t, b, l, r; int pt, pb, pl, pr; int i; int xarr[5], yarr[5]; double seg_len; const struct scale *scales = all_scales[use_feet]; /* Establish text size */ D_get_screen_window(&t, &b, &l, &r); R_set_window(t, b, l, r); R_text_size(size, size); x_pos = (int)(east * (r - l) / 100.); y_pos = (int)(north * (b - t) / 100.); if (draw == 1) { int w, h; w = 30; h = 17 + 2 * w; pl = x_pos; pt = y_pos; pr = x_pos + w + 2; /* 1 pixel margin for both sides */ pb = y_pos + h + 2; /* 1 pixel margin for both sides */ if (save) R_panel_save(save, pt, pb, pl, pr); if (do_background) { D_raster_use_color(color1); R_box_abs(pl, pt, pr, pb); } /* Draw legend */ D_raster_use_color(color2); R_move_abs(pl + w / 2 + 1, pt + 17 + 1); xarr[0] = 0; yarr[0] = 0; xarr[1] = -w / 2; yarr[1] = 2 * w; xarr[2] = w / 2; yarr[2] = -w / 2; xarr[3] = 0; yarr[3] = -1.5 * w; R_polyline_rel(xarr, yarr, 4); xarr[1] = -xarr[1]; xarr[2] = -xarr[2]; R_polygon_rel(xarr, yarr, 4); /* actual text width is 81% of size? from d.legend */ R_move_abs((int)(pl + w / 2 - 7 * .81), pt + 14); R_text("N"); R_stabilize(); return 0; } meters = D_get_u_east() - D_get_u_west(); meters *= G_database_units_to_meters_factor(); /* find the right scale */ for (incr = 0; incr < NUMSCALES; incr++) { if (meters <= scales[incr].limit) break; } if (!incr) return (-1); /* beyond the maximum just make the longest scale narrower */ if (incr >= NUMSCALES) incr = NUMSCALES - 1; line_len = D_get_u_to_d_xconv() * scales[incr].size / G_database_units_to_meters_factor(); seg_len = line_len / scales[incr].seg; /* work around round off */ line_len = ((int)seg_len) * scales[incr].seg; /* Blank out area with background color */ if (toptext) { pr = x_pos + 35 + (int)line_len; pt = y_pos - 15; if (pt < t) pt = t; } else { pr = x_pos + 35 + (int)line_len + size * strlen(scales[incr].name); pt = y_pos + 0; if (pt < t) pt = t; } pb = y_pos + 30; if (pb > b) pb = b; pl = x_pos + 0; if (pl < l) pl = l; pr = pr; if (pr > r) pr = r; if (save) R_panel_save(save, pt, pb, pl, pr); if (do_background) { D_raster_use_color(color1); R_box_abs(pl, pt, pr, pb); } /* Draw legend */ D_raster_use_color(color2); if (draw != 2) { R_move_abs(x_pos + 5, y_pos + 20); R_cont_rel(0, -10); R_cont_rel(10, 10); R_cont_rel(0, -10); R_move_rel(-5, 14); R_cont_rel(0, -17); R_cont_rel(-2, -0); R_cont_rel(2, -2); R_cont_rel(2, 2); R_cont_rel(-2, -0); } if (draw == 2) { R_move_abs(x_pos + 25 - draw * 10, y_pos + 17); /* actual width is line_len-1+1=line_len and height is 7+1=8 */ R_cont_rel((int)line_len - 1, 0); R_cont_rel(0, -7); R_cont_rel((int)(line_len * -1 + 1), 0); R_cont_rel(0, 7); R_move_rel(0, 1 - 4); for (i = 1; i <= scales[incr].seg; i++) { xarr[0] = 0; yarr[0] = 0; xarr[1] = (int)seg_len; yarr[1] = 0; xarr[2] = 0; yarr[2] = (i % 2 ? -4 : 4); xarr[3] = (int)-seg_len; yarr[3] = 0; xarr[4] = 0; yarr[4] = (i % 2 ? 4 : -4); /* width is seg_len and height is 4 */ R_polygon_rel(xarr, yarr, 4); R_move_rel((int)seg_len, 0); } } else if (do_bar) { R_move_abs(x_pos + 25, y_pos + 17); /* actual width is line_len-1+1=line_len and height is 4+1=5 */ R_cont_rel((int)line_len - 1, 0); R_cont_rel(0, -4); R_cont_rel((int)(line_len * -1 + 1), 0); R_cont_rel(0, 4); R_move_rel(0, 1); for (i = 1; i <= scales[incr].seg; i += 2) { /* width is seg_len and height is 5 */ R_box_rel((int)seg_len, -5); R_move_rel((int)(seg_len * 2), 0); } } else { /* draw simple line scale */ R_move_abs(x_pos + 25, y_pos + 5); R_cont_abs(x_pos + 25, y_pos + 25); R_move_abs(x_pos + 25, y_pos + 15); R_cont_abs(x_pos + 25 + (int)line_len, y_pos + 15); R_move_abs(x_pos + 25 + (int)line_len, y_pos + 5); R_cont_abs(x_pos + 25 + (int)line_len, y_pos + 25); } if (toptext) { R_move_abs(x_pos + 25 - draw * 10 + (int)(line_len / 2. - strlen(scales[incr].name) * size * 0.81 / 2), y_pos); R_text(scales[incr].name); } else { R_move_abs(x_pos + 35 - draw * 10 + (int)line_len, y_pos + 20); R_text(scales[incr].name); } R_stabilize(); return (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); } }
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; }