/* Same as path() but get start/stop from the command line (for non-interactive use) Hamish Bowman March 2007 */ int coor_path(struct Map_info *Map, const struct color_rgb *hcolor, int be_bold, double start_x, double start_y, double end_x, double end_y) { int ret; double nx, ny, fx, fy, tx, ty, msize, maxdist; struct line_pnts *Points; int start_node, end_node; double fdist, tdist, cost; Points = Vect_new_line_struct(); msize = 10 * (D_d_to_u_col(2.0) - D_d_to_u_col(1.0)); /* do it better */ G_debug(1, "msize = %f\n", msize); /* x1 = D_d_to_u_col ((double)(screen_x-WDTH)); y1 = D_d_to_u_row ((double)(screen_y-WDTH)); x2 = D_d_to_u_col ((double)(screen_x+WDTH)); y2 = D_d_to_u_row ((double)(screen_y+WDTH)); x1 = fabs ( x2 - x1 ); y1 = fabs ( y2 - y1 ); if ( x1 > y1 ) maxdist = x1; else maxdist = y1; */ /** maxdist = 10 pixels on the display (WDTH*2); ? ** ie related to zoom level ?? just use msize ?? **/ maxdist = msize; G_debug(1, "Maximum distance in map units = %f\n", maxdist); /* Vect_find_node(): find number of nearest node, 0 if not found */ start_node = Vect_find_node(Map, start_x, start_y, 0.0, maxdist, 0); if (start_node > 0) { Vect_get_node_coor(Map, start_node, &nx, &ny, NULL); fprintf(stderr, _("Node %d: %f %f\n"), start_node, nx, ny); } if (start_node > 0) { fx = nx; fy = ny; } else { fx = start_x; fy = start_y; } D_RGB_color(hcolor->r, hcolor->g, hcolor->b); D_plot_icon(fx, fy, G_ICON_BOX, 0.0, msize); end_node = Vect_find_node(Map, end_x, end_y, 0.0, maxdist, 0); if (end_node > 0) { Vect_get_node_coor(Map, end_node, &nx, &ny, NULL); fprintf(stderr, _("Node %d: %f %f\n"), end_node, nx, ny); } if (end_node > 0) { tx = nx; ty = ny; } else { tx = end_x; ty = end_y; } D_RGB_color(hcolor->r, hcolor->g, hcolor->b); D_plot_icon(tx, ty, G_ICON_CROSS, 0.0, msize); G_debug(2, "find path %f %f -> %f %f", fx, fy, tx, ty); ret = Vect_net_shortest_path_coor(Map, fx, fy, 0.0, tx, ty, 0.0, 5 * maxdist, 5 * maxdist, &cost, Points, NULL, NULL, NULL, NULL, &fdist, &tdist); if (ret == 0) { fprintf(stdout, _("Destination unreachable\n")); } else { fprintf(stdout, _("Costs on the network = %f\n"), cost); fprintf(stdout, _(" Distance to the network = %f, " "distance from the network = %f\n\n"), fdist, tdist); display(Map, Points, hcolor, 1, 1, be_bold); } return 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; }
int draw_n_arrow(double east, double north, double rotation, char *lbl, int rot_with_text, double fontsize, char *n_arrow_num, double line_width) { double x_pos, y_pos; double t, b, l, r; double tt, tb, tl, tr; /* text box */ SYMBOL *Symb; RGBA_Color *line_color, *fill_color; int R, G, B; double x0, y0; char icon[64]; double symbol_size; /* Establish text size */ if (fontsize > 0) D_text_size(fontsize, fontsize); D_setup_unity(0); D_get_src(&t, &b, &l, &r); x_pos = l + (int)(east * (r - l) / 100.); y_pos = t + (int)((100. - north) * (b - t) / 100.); if (line_width > 0) D_line_width(line_width); if (fontsize > 0) { /* draw the label (default "N") */ if (rot_with_text) D_text_rotation(rotation * 180.0 / M_PI); D_get_text_box(lbl, &tt, &tb, &tl, &tr); D_use_color(text_color); /* positions manually tuned */ switch (n_arrow_num[0]) { case '1': D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2, y_pos - cos(rotation) * 50 - (tb + tt) / 2); D_text(lbl); break; case '3': D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2, y_pos - cos(rotation) * 60 - (tb + tt) / 2); D_text(lbl); break; case '4': D_pos_abs(x_pos - sin(rotation) * 45 - (tr + tl) / 2, y_pos - cos(rotation) * 45 - (tb + tt) / 2); D_text(lbl); break; case '7': D_pos_abs(x_pos - sin(rotation) * 70 - (tr + tl) / 2, y_pos - cos(rotation) * 70 - (tb + tt) / 2); D_text(lbl); break; case '8': D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2, y_pos - cos(rotation) * 60 - (tb + tt) / 2); D_text(lbl); break; case '9': D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2, y_pos - cos(rotation) * 55 - (tb + tt) / 2); D_text(lbl); break; case 'f': D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2, y_pos - cos(rotation) * 55 - (tb + tt) / 2); D_text(lbl); break; case 'b': D_pos_abs(x_pos - sin(rotation) * 48.5 - (tr + tl) / 2, y_pos - cos(rotation) * 48.5 - (tb + tt) / 2); D_text(lbl); break; case 'a': D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2, y_pos - cos(rotation) * 50 - (tb + tt) / 2); D_text(lbl); break; case 's': D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2, y_pos - cos(rotation) * 50 - (tb + tt) / 2); D_text(lbl); break; case '2': case '5': case '6': break; default: G_fatal_error(_("Could not parse symbol")); } } /* display the north arrow symbol */ line_color = G_malloc(sizeof(RGBA_Color)); fill_color = G_malloc(sizeof(RGBA_Color)); if (D_color_number_to_RGB(fg_color, &R, &G, &B) == 0) line_color->a = RGBA_COLOR_TRANSPARENT; else line_color->a = RGBA_COLOR_OPAQUE; line_color->r = (unsigned char)R; line_color->g = (unsigned char)G; line_color->b = (unsigned char)B; if (D_color_number_to_RGB(bg_color, &R, &G, &B) == 0) fill_color->a = RGBA_COLOR_TRANSPARENT; else fill_color->a = RGBA_COLOR_OPAQUE; fill_color->r = (unsigned char)R; fill_color->g = (unsigned char)G; fill_color->b = (unsigned char)B; /* sizes manually tuned */ switch (n_arrow_num[0]) { case '1': symbol_size = 35.; break; case '2': symbol_size = 19.; break; case '3': symbol_size = 20.; break; case '4': symbol_size = 15.; break; case '5': case '6': symbol_size = 14.; break; case '7': symbol_size = 23.; break; case '8': case '9': symbol_size = 17.; break; case 'b': symbol_size = 80.; break; case 'f': symbol_size = 100.; break; case 'a': if (n_arrow_num[5] == '2') symbol_size = 53.; else symbol_size = 70.; break; case 's': symbol_size = 80.; break; default: G_fatal_error(_("Could not parse symbol")); } x0 = D_d_to_u_col(x_pos); y0 = D_d_to_u_row(y_pos); if (n_arrow_num[0] == 'b') strcpy(icon, "n_arrows/basic_compass"); else if (n_arrow_num[0] == 'f') strcpy(icon, "n_arrows/fancy_compass"); else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '1') strcpy(icon, "basic/arrow1"); else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '2') strcpy(icon, "basic/arrow2"); else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '3') strcpy(icon, "basic/arrow3"); else if (n_arrow_num[0] == 's') strcpy(icon, "extra/4pt_star"); else { strcpy(icon, "n_arrows/n_arrow"); strncat(icon, n_arrow_num, 32); } Symb = S_read(icon); if (!Symb) G_fatal_error(_("Could not read symbol \"%s\""), icon); S_stroke(Symb, symbol_size, rotation * (180 / M_PI), 0); D_symbol(Symb, x0, y0, line_color, fill_color); if (line_width > 0) D_line_width(0); G_free(Symb); G_free(line_color); G_free(fill_color); return 0; }
int move_line_update(void *closure, int sxn, int syn, int button) { struct move_line *ml = closure; double x = D_d_to_u_col(sxn); double y = D_d_to_u_row(syn); G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y); if (ml->last_line > 0) { display_line(ml->last_line, SYMB_DEFAULT, 1); } if (button == 3) return 1; if (button == 1) { /* Select / new location */ int type; if (ml->last_line == 0) { /* Select line */ ml->line = Vect_find_line(&Map, x, y, 0, GV_POINT | GV_CENTROID, ml->thresh, 0, 0); G_debug(2, "point found = %d", ml->line); if (ml->line == 0) ml->line = Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY, ml->thresh, 0, 0); G_debug(2, "line found = %d", ml->line); /* Display new selected line if any */ if (ml->line > 0) { display_line(ml->line, SYMB_HIGHLIGHT, 1); /* Find the nearest point on the line */ type = Vect_read_line(&Map, ml->Points, NULL, ml->line); Vect_line_distance(ml->Points, x, y, 0, 0, &ml->xo, &ml->yo, NULL, NULL, NULL, NULL); set_location(D_u_to_d_col(ml->xo), D_u_to_d_row(ml->yo)); i_prompt_buttons(_("New location"), _("Unselect"), _("Quit tool")); } ml->last_line = ml->line; } else { /* Line is already selected */ int node1, node2; int i; display_line(ml->last_line, SYMB_BACKGROUND, 1); Vect_get_line_nodes(&Map, ml->last_line, &node1, &node2); display_node(node1, SYMB_BACKGROUND, 1); display_node(node2, SYMB_BACKGROUND, 1); type = Vect_read_line(&Map, ml->Points, ml->Cats, ml->last_line); for (i = 0; i < ml->Points->n_points; i++) { ml->Points->x[i] = ml->Points->x[i] + x - ml->xo; ml->Points->y[i] = ml->Points->y[i] + y - ml->yo; } Vect_rewrite_line(&Map, ml->last_line, type, ml->Points, ml->Cats); updated_lines_and_nodes_erase_refresh_display(); ml->last_line = 0; } } if (button == 2) { /* Unselect */ if (ml->last_line > 0) { ml->last_line = 0; } } if (ml->last_line == 0) { i_prompt_buttons(_("Select"), "", _("Quit tool")); set_mode(MOUSE_POINT); } else set_mode(MOUSE_LINE); return 0; }
int delete_line_update(void *closure, int sxn, int syn, int button) { struct delete_line *dl = closure; double x = D_d_to_u_col(sxn); double y = D_d_to_u_row(syn); G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y); /* Display last highlighted in normal color */ if (dl->last_line > 0) { display_line(dl->last_line, SYMB_DEFAULT, 1); } if (button == 3) /* Quit tool */ return 1; if (button == 1) { /* Confirm / select */ /* Delete last if any */ if (dl->last_line > 0) { int node1, node2; int i; /* Erase line and nodes !!! (because if the line is not connected to any other, nodes will die */ display_line(dl->last_line, SYMB_BACKGROUND, 1); Vect_get_line_nodes(&Map, dl->line, &node1, &node2); G_debug(2, "delete line = %d node1 = %d node2 = %d", dl->last_line, node1, node2); display_node(node1, SYMB_BACKGROUND, 1); display_node(node2, SYMB_BACKGROUND, 1); Vect_read_line(&Map, NULL, dl->Cats, dl->last_line); Vect_delete_line(&Map, dl->last_line); for (i = 0; i < dl->Cats->n_cats; i++) { check_record(dl->Cats->field[i], dl->Cats->cat[i]); } for (i = 0; i < Vect_get_num_updated_lines(&Map); i++) G_debug(2, "Updated line: %d", Vect_get_updated_line(&Map, i)); for (i = 0; i < Vect_get_num_updated_nodes(&Map); i++) G_debug(2, "Updated node: %d", Vect_get_updated_node(&Map, i)); updated_lines_and_nodes_erase_refresh_display(); } /* Find neares point or line */ dl->line = Vect_find_line(&Map, x, y, 0, GV_POINT | GV_CENTROID, dl->thresh, 0, 0); G_debug(2, "point found = %d", dl->line); if (dl->line == 0) dl->line = Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY, dl->thresh, 0, 0); G_debug(2, "line found = %d", dl->line); /* Display new selected line if any */ if (dl->line > 0) { display_line(dl->line, SYMB_HIGHLIGHT, 1); } } else { /* button == 2 -> unselect */ dl->line = 0; } if (dl->line > 0) i_prompt_buttons(_("Confirm and select next"), _("Unselect"), _("Quit tool")); else i_prompt_buttons(_("Select"), _("Unselect"), _("Quit tool")); dl->last_line = dl->line; dl->first = 0; return 0; }
int edit_line_update(void *closure, int sxn, int syn, int button) { struct edit_line *el = closure; double x = D_d_to_u_col(sxn); double y = D_d_to_u_row(syn); G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y); if (button == 3) /* Tool broken by GUI */ return 1; switch (el->phase) { case 1: if (button != 1) return 0; /* Find nearest point or line */ el->line = Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY, el->thresh, 0, 0); G_debug(2, "line found = %d", el->line); /* Display new selected line if any */ if (el->line > 0) { display_line(el->line, SYMB_HIGHLIGHT, 1); edit_line_phase2(el, x, y); } break; case 2: if (button == 1) { /* New point */ snap(&x, &y); Vect_append_point(el->Points, x, y, 0); if (el->line_type == GV_LINE) symb_set_driver_color(SYMB_LINE); else symb_set_driver_color(SYMB_BOUNDARY_0); display_points(el->Points, 1); set_location(sxn, syn); i_prompt_buttons(_("New Point"), _("Undo Last Point"), _("Close line")); } else if (button == 2) { /* Undo last point */ if (el->Points->n_points > 1) { symb_set_driver_color(SYMB_BACKGROUND); display_points(el->Points, 1); el->Points->n_points--; if (el->line_type == GV_LINE) symb_set_driver_color(SYMB_LINE); else symb_set_driver_color(SYMB_BOUNDARY_0); display_points(el->Points, 1); set_location(D_u_to_d_col (el->Points->x[el->Points->n_points - 1]), D_u_to_d_row(el->Points-> y[el->Points->n_points - 1]) ); if (el->Points->n_points == 1) i_prompt_buttons(_("New Point"), "", _("Delete line and exit")); } } break; } return 0; }
int new_line_update(void *closure, int sxn, int syn, int button) { struct new_line *nl = closure; double x = D_d_to_u_col(sxn); double y = D_d_to_u_row(syn); double dist; G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y); if (nl->first && button == 3) { /* Quit tool ( points & lines ), first is always for points */ Tool_next = TOOL_NOTHING; return 1; } if (button > 3) /* Do nothing on mouse scroll */ return 0; if (nl->type & GV_POINTS && (button == 1 || button == 2)) { snap(&x, &y); Vect_append_point(nl->Points, x, y, 0); write_line(&Map, nl->type, nl->Points); updated_lines_and_nodes_erase_refresh_display(); return 1; } else { /* GV_LINES */ /* Button may be 1,2,3 */ if (button == 1) { /* New point */ if (snap(&x, &y) == 0) { /* If not snapping to other features, try to snap to lines start. * Allows to create area of single boundary. */ if (nl->Points->n_points > 2) { dist = Vect_points_distance(nl->Points->x[0], nl->Points->y[0], 0, x, y, 0, WITHOUT_Z); if (dist < get_thresh()) { x = nl->Points->x[0]; y = nl->Points->y[0]; } } } if (Vect_append_point(nl->Points, x, y, 0) == -1) { G_warning(_("Out of memory! Point not added.")); return 0; } if (nl->type == GV_LINE) symb_set_driver_color(SYMB_LINE); else symb_set_driver_color(SYMB_BOUNDARY_0); display_points(nl->Points, 1); set_location(D_u_to_d_col(x), D_u_to_d_row(y)); nl->first = 0; set_mode(MOUSE_LINE); } else if (button == 2) { /* Undo last point */ if (nl->Points->n_points >= 1) { symb_set_driver_color(SYMB_BACKGROUND); display_points(nl->Points, 1); nl->Points->n_points--; if (nl->type == GV_LINE) symb_set_driver_color(SYMB_LINE); else symb_set_driver_color(SYMB_BOUNDARY_0); display_points(nl->Points, 1); set_location(D_u_to_d_col (nl->Points->x[nl->Points->n_points - 1]), D_u_to_d_row(nl->Points-> y[nl->Points->n_points - 1]) ); } if (nl->Points->n_points == 0) { i_prompt_buttons(_("New point"), "", _("Quit tool")); nl->first = 1; set_mode(MOUSE_POINT); } } else if (button == 3) { /* write the line and quit */ if (nl->Points->n_points > 1) { /* Before the line is written, we must check if connected to existing nodes, if yes, * such nodes must be add to update list before! the line is written (areas/isles */ int node1 = Vect_find_node(&Map, nl->Points->x[0], nl->Points->y[0], nl->Points->z[0], 0, Vect_is_3d(&Map)); int i = nl->Points->n_points - 1; int node2 = Vect_find_node(&Map, nl->Points->x[i], nl->Points->y[i], nl->Points->z[i], 0, Vect_is_3d(&Map)); G_debug(2, " old node1 = %d old node2 = %d", node1, node2); write_line(&Map, nl->type, nl->Points); updated_lines_and_nodes_erase_refresh_display(); } else G_warning(_("Less than 2 points for line -> nothing written")); return 1; } G_debug(2, "n_points = %d", nl->Points->n_points); } i_prompt_buttons(_("New point"), _("Undo last point"), _("Close line")); return 0; }