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); }
static void arrow_360(double theta) { /* angle is measured in degrees counter-clockwise from east */ double x, y, dx, dy, mid_x, mid_y; double max_radius, theta_offset; theta *= -1; /* display coords use inverse y */ max_radius = 0.8 / 2; /* find the display coordinates of the middle of the cell */ mid_x = col + (0.5); mid_y = row + (0.5); D_begin(); /* head */ x = mid_x + (max_radius * cos(D2R(theta))); y = mid_y + (max_radius * sin(D2R(theta))); D_move_abs(x, y); /* tail */ dx = -2 * (max_radius * cos(D2R(theta))); dy = -2 * (max_radius * sin(D2R(theta))); D_cont_rel(dx, dy); /* fin 1 */ D_move_abs(x, y); theta_offset = theta + 90; dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset))); dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset))); D_cont_abs(dx, dy); /* fin 2 */ D_move_abs(x, y); theta_offset = theta - 90; dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset))); dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset))); D_cont_abs(dx, dy); D_end(); D_stroke(); }
static void arrow_mag(double theta, double length) { /* angle is measured in degrees counter-clockwise from east */ double x, y, dx, dy, mid_x, mid_y; double theta_offset; theta *= -1; /* display coords use inverse y */ /* find the display coordinates of the middle of the cell */ mid_x = col + (.5); mid_y = row + (.5); D_begin(); /* tail */ D_move_abs(mid_x, mid_y); /* head */ x = mid_x + (length * cos(D2R(theta))); y = mid_y + (length * sin(D2R(theta))); D_cont_abs(x, y); /* fin 1 */ theta_offset = theta + 20; dx = mid_x + (0.6 * length * cos(D2R(theta_offset))); dy = mid_y + (0.6 * length * sin(D2R(theta_offset))); D_cont_abs(dx, dy); /* fin 2 */ D_move_abs(x, y); theta_offset = theta - 20; dx = mid_x + (0.6 * length * cos(D2R(theta_offset))); dy = mid_y + (0.6 * length * sin(D2R(theta_offset))); D_cont_abs(dx, dy); D_end(); D_stroke(); }
void plot(double lon1, double lat1, double lon2, double lat2, int line_color, int text_color) { int nsteps = 1000; int i; D_setup(0); D_use_color(line_color); if (lon1 == lon2) { D_line_abs(lon1, lat1, lon2, lat2); return; } if (lon1 > lon2) { double tmp = lon1; lon1 = lon2; lon2 = tmp; } G_shortest_way(&lon1, &lon2); G_begin_rhumbline_equation(lon1, lat1, lon2, lat2); D_begin(); for (i = 0; i <= nsteps; i++) { double lon = lon1 + (lon2 - lon1) * i / nsteps; double lat = G_rhumbline_lat_from_lon(lon); if (i == 0) D_move_abs(lon, lat); else D_cont_abs(lon, lat); } D_end(); D_stroke(); }
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 D_cont_rel(int x, int y) { return D_cont_abs(curx + x, cury + y); }
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 main(int argc, char **argv) { struct GModule *module; struct Option *map, *profile; struct Flag *stored; struct Cell_head window; struct point *points = NULL; int num_points, max_points = 0; double length; double t, b, l, r; int fd; int i; double sx; int last; /* Initialize the GIS calls */ G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("profile")); G_add_keyword(_("raster")); module->description = _("Plots profile of a transect."); /* set up command line */ map = G_define_standard_option(G_OPT_R_INPUT); map->description = _("Raster map to be profiled"); profile = G_define_option(); profile->key = "profile"; profile->type = TYPE_DOUBLE; profile->required = YES; profile->multiple = YES; profile->key_desc = "east,north"; profile->description = _("Profile coordinate pairs"); stored = G_define_flag(); stored->key = 'r'; stored->description = _("Use map's range recorded range"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); mapname = map->answer; fd = Rast_open_old(mapname, ""); if (stored->answer) get_map_range(); else get_region_range(fd); G_get_window(&window); num_points = 0; length = 0; for (i = 0; profile->answers[i]; i += 2) { struct point *p; double x, y; if (num_points >= max_points) { max_points = num_points + 100; points = G_realloc(points, max_points * sizeof(struct point)); } p = &points[num_points]; G_scan_easting( profile->answers[i+0], &x, G_projection()); G_scan_northing(profile->answers[i+1], &y, G_projection()); p->x = Rast_easting_to_col (x, &window); p->y = Rast_northing_to_row(y, &window); if (num_points > 0) { const struct point *prev = &points[num_points-1]; double dx = fabs(p->x - prev->x); double dy = fabs(p->y - prev->y); double d = sqrt(dx * dx + dy * dy); length += d; p->d = length; } num_points++; } points[0].d = 0; if (num_points < 2) G_fatal_error(_("At least two points are required")); /* establish connection with graphics driver */ if (D_open_driver() != 0) G_fatal_error(_("No graphics device selected. " "Use d.mon to select graphics device.")); D_setup2(1, 0, 1.05, -0.05, -0.15, 1.05); plot_axes(); D_use_color(D_translate_color(DEFAULT_FG_COLOR)); D_get_src(&t, &b, &l, &r); t -= 0.1 * (t - b); b += 0.1 * (t - b); l += 0.1 * (r - l); r -= 0.1 * (r - l); D_begin(); i = 0; last = 0; for (sx = 0; sx < 1; sx += D_get_d_to_u_xconv()) { double d = length * (sx - l); const struct point *p, *next; double k, sy, x, y; DCELL v; for (;;) { p = &points[i]; next = &points[i + 1]; k = (d - p->d) / (next->d - p->d); if (k < 1) break; i++; } x = p->x * (1 - k) + next->x * k; y = p->y * (1 - k) + next->y * k; if (!get_cell(&v, fd, x, y)) { last = 0; continue; } sy = (v - min) / (max - min); if (last) D_cont_abs(sx, sy); else D_move_abs(sx, sy); last = 1; } D_end(); D_stroke(); D_close_driver(); exit(EXIT_SUCCESS); }