int make_window_box(struct Cell_head *window, double magnify, int full, int hand) { int screen_x, screen_y; double px, py, ux1, uy1, ux2, uy2; double ns, ew; int button; int cur_screen_x, cur_screen_y; int mode; /* 1, 2 */ int resetwin; struct Cell_head defwin; int printmenu = 1; G_get_default_window(&defwin); mode = 1; while (1) { resetwin = 0; if (!hand) { if (printmenu) { fprintf(stderr, "\n\nButtons:\n"); fprintf(stderr, "Left: 1. corner\n"); fprintf(stderr, "Middle: Unzoom\n"); if (full) fprintf(stderr, "Right: Main menu\n\n"); else fprintf(stderr, "Right: Quit\n\n"); printmenu = 0; } } else { if (mode == 1) fprintf(stderr, "\r1. corner"); else fprintf(stderr, "\r2. corner"); } if (mode == 1) { if (!hand) { R_get_location_with_pointer(&screen_x, &screen_y, &button); } else { R_get_location_with_box(0, 0, &screen_x, &screen_y, &button); } cur_screen_x = screen_x; cur_screen_y = screen_y; } else { R_get_location_with_box(cur_screen_x, cur_screen_y, &screen_x, &screen_y, &button); } /* For print only */ px = D_d_to_u_col((double)screen_x); py = D_d_to_u_row((double)screen_y); if (!hand) print_coor(window, py, px); if (button == 1) { if (!hand) { if (mode == 1) { fprintf(stderr, "\n\nButtons:\n"); fprintf(stderr, "Left: 1. corner (reset)\n"); fprintf(stderr, "Middle: 2. corner\n"); if (full) fprintf(stderr, "Right: Main menu\n\n"); else fprintf(stderr, "Right: Quit\n\n"); mode = 2; } if (mode == 2) { cur_screen_x = screen_x; cur_screen_y = screen_y; } } else { /* hand */ if (mode == 1) { mode = 2; } else { ux1 = D_d_to_u_col((double)cur_screen_x); uy1 = D_d_to_u_row((double)cur_screen_y); ux2 = D_d_to_u_col((double)screen_x); uy2 = D_d_to_u_row((double)screen_y); resetwin = 1; mode = 1; } } } else if (button == 2) { if (mode == 1) { /* unzoom */ ux2 = D_d_to_u_col((double)screen_x); uy2 = D_d_to_u_row((double)screen_y); ew = window->east - window->west; ns = window->north - window->south; if (ns <= window->ns_res) ns = 2 * window->ns_res; else ew /= magnify; if (ew <= window->ew_res) ew = 2 * window->ew_res; else ns /= magnify; ux1 = window->east + ew / 2; ux2 = window->west - ew / 2; uy1 = window->north + ns / 2; uy2 = window->south - ns / 2; } else { ux1 = D_d_to_u_col((double)cur_screen_x); uy1 = D_d_to_u_row((double)cur_screen_y); ux2 = D_d_to_u_col((double)screen_x); uy2 = D_d_to_u_row((double)screen_y); printmenu = 1; mode = 1; } fprintf(stderr, "\n"); resetwin = 1; } else { fprintf(stderr, "\n"); return 1; } if (resetwin) { set_win(window, ux1, uy1, ux2, uy2, hand); } } fprintf(stderr, "\n"); return 1; /* not reached */ }
static void graph_unit(int t, int b, int l, int r, char *n1, char *n2, char *n3, double *mx, int fmask) { int x0 = 0, y0 = 0, xp, yp, ux[250], uy[250], u_w, u_l, btn = 0, k = 0, w_w = 0, w_l = 0, *row_buf, at, ab, al, ar, circle = 0, tmpw, tmpl, au_w, au_l, lap = 0, l0 = 0, r0 = 0, t0 = 0, b0 = 0; FILE *fp; double tmp, radius = 0.0; register int i, j; /* VARIABLES: COORDINATES IN THIS ROUTINE ARE IN CELLS t = top row of sampling frame b = bottom row of sampling frame l = left col of sampling frame r = right col of sampling frame n1 = n2 = n3 = mx[0] = cols of region/width of screen mx[1] = rows of region/height of screen xp = mouse x location in screen coordinates (col) yp = mouse y location in screen coordinates (row) ar = mouse x location in map coordinates (col) al = mouse y location in map coordinates (row) */ l0 = l; r0 = r; t0 = t; b0 = b; l = (int)((double)(l * mx[0]) + 0.5); r = (int)((double)(r * mx[0]) + 0.5); t = (int)((double)(t * mx[1]) + 0.5); b = (int)((double)(b * mx[1]) + 0.5); w_w = r - l; w_l = b - t; /* draw the sampling frame */ R_open_driver(); R_standard_color(D_translate_color("grey")); draw_box((int)(l / mx[0]), (int)(t / mx[1]), (int)(r / mx[0]), (int)(b / mx[1]), 1); R_close_driver(); fp = fopen0("r.le.para/units", "w"); G_sleep_on_error(0); /* get the number of scales */ do { fprintf(stderr, "\n How many different SCALES do you want? (1-15) "); numtrap(1, &tmp); if (tmp < 1 || tmp > 15) fprintf(stderr, " Too many (>15) or too few scales, try again.\n"); } while (tmp < 1 || tmp > 15); fprintf(fp, "%10d # of scales\n", (int)(tmp)); /* for each scale */ for (i = 0; i < tmp; i++) { G_system("clear"); radius = 0.0; circle = 0; /* if sampling using circles */ fprintf(stderr, "\n SCALE %d\n", i + 1); fprintf(stderr, "\n Do you want to sample using rectangles"); if (!G_yes("\n (including squares) (y) or circles (n)? ", 1)) { circle = 1; fprintf(stderr, "\n Draw a rectangular area to contain a standard circular"); fprintf(stderr, "\n sampling unit of scale %d. First select upper left", i + 1); fprintf(stderr, "\n corner, then lower right:\n"); fprintf(stderr, " Left button: Check unit size\n"); fprintf(stderr, " Middle button: Upper left corner of area here\n"); fprintf(stderr, " Right button: Lower right corner of area here\n"); } else { fprintf(stderr, "\n Draw a standard rectangular unit of scale %d.", i + 1); fprintf(stderr, "\n First select upper left corner, then lower right:\n"); fprintf(stderr, " Left button: Check unit size\n"); fprintf(stderr, " Middle button: Upper left corner of unit here\n"); fprintf(stderr, " Right button: Lower right corner of unit here\n"); } R_open_driver(); do { back1: R_get_location_with_box(x0, y0, &xp, &yp, &btn); /* convert the upper left screen coordinate (x0, y0) and the mouse position (xp, yp) on the screen to the nearest row and column; do the same for the sampling unit width (u_w) and height (u_l); then convert back */ ar = (int)((double)(xp) * mx[0] + 0.5); xp = (int)((double)(ar) / mx[0] + 0.5); al = (int)((double)(x0) * mx[0] + 0.5); x0 = (int)((double)(al) / mx[0] + 0.5); au_w = ar - al; u_w = (int)((double)(au_w) / mx[0] + 0.5); ab = (int)((double)(yp) * mx[1] + 0.5); yp = (int)((double)(ab) / mx[1] + 0.5); at = (int)((double)(y0) * mx[1] + 0.5); y0 = (int)((double)(at) / mx[1] + 0.5); au_l = ab - at; u_l = (int)((double)(au_l) / mx[1] + 0.5); /* left button, check the size of the rubber box in array system */ if (btn == 1) { if (ar > r || ab > b || ar < l || ab < t) { fprintf(stderr, "\n This point is not in the sampling frame; try again\n"); goto back1; } if (x0 < l || y0 < t) { fprintf(stderr, "\n Use the middle button to first put the upper left"); fprintf(stderr, "\n corner inside the sampling frame\n"); goto back1; } if (ar <= al || ab <= at) { fprintf(stderr, "\n Please put the lower right corner down and to"); fprintf(stderr, "\n the right of the upper left corner\n"); goto back1; } else { fprintf(stderr, "\n Unit would be %d columns wide by %d rows long\n", abs(au_w), abs(au_l)); fprintf(stderr, " Width/length would be %5.2f and size %d pixels\n", (double)abs((au_w)) / (double)abs((au_l)), abs(au_w) * abs(au_l)); } } /* mid button, move the start point of the rubber box */ else if (btn == 2) { if (ar > r || ab > b || ar < l || ab < t) { fprintf(stderr, "\n Point is not in the sampling frame; try again\n"); goto back1; } else { R_move_abs(xp, yp); x0 = xp; y0 = yp; } } /* right button, outline the unit */ else if (btn == 3) { if (circle) { if (u_w > u_l) { al = al + ((ar - al) - (ab - at)) / 2; ar = al + (ab - at); x0 = (int)((double)(al) / mx[0] + 0.5); xp = (int)((double)(ar) / mx[0] + 0.5); au_w = ar - al; u_w = u_l = (int)((double)(au_w) / mx[0] + 0.5); } if (u_l > u_w) { at = at + ((ab - at) - (ar - al)) / 2; ab = at + (ar - al); y0 = (int)((double)(at) / mx[1] + 0.5); yp = (int)((double)(ab) / mx[1] + 0.5); au_l = ab - at; u_w = u_l = (int)((double)(au_l) / mx[1] + 0.5); } } if (ar > r || ab > b || al < l || at < t) { fprintf(stderr, "\n The unit extends outside the sampling frame or map;"); fprintf(stderr, "\n try again\n"); goto back1; } if (au_w > w_w || au_l > w_l) { fprintf(stderr, "\n The unit is too big for the sampling frame; "); fprintf(stderr, "try again\n"); goto back1; } /* if there is a mask, check to see that the unit will be within the mask area, by checking to see whether the four corners of the unit are in the mask */ if (fmask > 0) { row_buf = Rast_allocate_c_buf(); Rast_get_c_row_nomask(fmask, row_buf, at); if (!(*(row_buf + al) && *(row_buf + ar - 1))) { fprintf(stderr, "\n The unit would be outside the mask; "); fprintf(stderr, "try again\n"); G_free(row_buf); goto back1; } Rast_zero_c_buf(row_buf); Rast_get_c_row_nomask(fmask, row_buf, ab - 1); if (!(*(row_buf + al) && *(row_buf + ar - 1))) { fprintf(stderr, "\n The unit would be outside the mask; "); fprintf(stderr, "try again\n"); G_free(row_buf); goto back1; } G_free(row_buf); } if (xp - x0 > 0 && yp - y0 > 0) { R_standard_color(D_translate_color("red")); if (circle) draw_circle(x0, y0, xp, yp, 3); else draw_box(x0, y0, xp, yp, 1); G_system("clear"); if (circle) { fprintf(stderr, "\n\n The standard circular sampling unit has:\n"); fprintf(stderr, " radius = %f pixels\n", (double)(ar - al) / 2.0); } else { fprintf(stderr, "\n\n The standard sampling unit has:\n"); fprintf(stderr, " columns=%d rows=%d\n", abs(ar - al), abs(ab - at)); fprintf(stderr, " width/length ratio=%5.2f\n", (double)abs(ar - al) / (double)abs(ab - at)); fprintf(stderr, " size=%d pixels\n", abs(ar - al) * abs(ab - at)); } k = 0; ux[0] = al; uy[0] = at; } else if (xp - x0 == 0 || yp - y0 == 0) { fprintf(stderr, "\n Unit has 0 rows and/or 0 columns; try again\n"); goto back1; } else { fprintf(stderr, "\n You did not put the lower right corner below"); fprintf(stderr, "\n and to the right of the upper left corner. Please try again"); goto back1; } } } while (btn != 3); R_close_driver(); /* use the size and shape of the standard unit to outline more units in that scale */ fprintf(stderr, "\n Outline more sampling units of scale %d?\n", i + 1); fprintf(stderr, " Left button: Exit\n"); fprintf(stderr, " Middle button: Check unit position\n"); fprintf(stderr, " Right button: Lower right corner of next unit here\n"); R_open_driver(); /* if not the left button (to exit) */ back2: while (btn != 1) { R_get_location_with_box(xp - u_w, yp - u_l, &xp, &yp, &btn); /* convert the left (x0), right (y0), top (y0), bottom (yp) coordinates in screen pixels to the nearest row and column; do the same for the sampling unit width (u_w) and height (u_l); then convert back */ ar = (int)((double)(xp) * mx[0] + 0.5); ab = (int)((double)(yp) * mx[1] + 0.5); xp = (int)((double)(ar) / mx[0] + 0.5); yp = (int)((double)(ab) / mx[1] + 0.5); al = (int)((double)(xp - u_w) * mx[0] + 0.5); at = (int)((double)(yp - u_l) * mx[0] + 0.5); x0 = (int)((double)(al) / mx[0] + 0.5); y0 = (int)((double)(at) / mx[1] + 0.5); /* if right button, outline the unit */ if (btn == 3) { if (ar > r || ab > b || al < l || at < t) { fprintf(stderr, "\n The unit would be outside the map; try again"); goto back2; } /* if there is a mask, check to see that the unit will be within the mask area */ if (fmask > 0) { row_buf = Rast_allocate_c_buf(); Rast_get_c_row_nomask(fmask, row_buf, at); if (!(*(row_buf + al) && *(row_buf + ar - 1))) { fprintf(stderr, "\n The unit would be outside the mask; "); fprintf(stderr, "try again"); G_free(row_buf); goto back2; } Rast_zero_c_buf(row_buf); Rast_get_c_row_nomask(fmask, row_buf, ab - 1); if (!(*(row_buf + al) && *(row_buf + ar - 1))) { fprintf(stderr, "\n The unit would be outside the mask; "); fprintf(stderr, "try again"); G_free(row_buf); goto back2; } G_free(row_buf); } /* check for sampling unit overlap */ lap = 0; for (j = 0; j < k + 1; j++) { if (overlap(al, at, ux[j], uy[j], au_w, au_l)) { fprintf(stderr, "\n The unit would overlap a previously drawn "); fprintf(stderr, "unit; try again"); lap = 1; } } if (lap) goto back2; k++; fprintf(stderr, "\n %d sampling units have been placed", (k + 1)); ux[k] = al; uy[k] = at; R_standard_color(D_translate_color("red")); if (circle) draw_circle(x0, y0, xp, yp, 3); else draw_box(x0, y0, xp, yp, 1); } } R_close_driver(); /* save the sampling units in the r.le.para/units file */ if (circle) radius = (double)(ar - al) / 2.0; else radius = 0.0; fprintf(fp, "%10d # of units of scale %d\n", k + 1, i + 1); fprintf(fp, "%10d%10d u_w, u_l of units in scale %d\n", (int)(u_w * mx[0]), (int)(u_l * mx[1]), i + 1); fprintf(fp, "%10.1f radius of circles in scale %d\n", radius, (i + 1)); for (j = 0; j < k + 1; j++) fprintf(fp, "%10d%10d left, top of unit[%d]\n", ux[j], uy[j], j + 1); if (i < tmp - 1 && G_yes("\n Refresh the screen? ", 1)) { paint_map(n1, n2, n3); R_open_driver(); R_standard_color(D_translate_color("red")); R_close_driver(); } } fclose(fp); return; }
static void set_frame(double *msc, int *t, int *b, int *l, int *r) { int t0, b0, l0, r0, btn; /* record the initial boundaries of the map */ t0 = *t; b0 = *b; l0 = *l; r0 = *r; /* if the total area to be sampled will be the whole map */ G_system("clear"); if (G_yes ("\n Will the sampling frame (total area within which sampling\n units are distributed) be the whole map? ", 1)) { R_open_driver(); R_standard_color(D_translate_color("grey")); draw_box(*l, *t, *r, *b, 1); R_close_driver(); fprintf(stderr, "\n Sampling frame set to whole map"); } /* if the total area to be sampled is not the whole map, then have the user draw the area */ else { back: G_system("clear"); fprintf(stderr, " \n OUTLINE SAMPLING FRAME:\n"); R_open_driver(); fprintf(stderr, "\n Please move cursor to the UPPER-LEFT corner of\n"); fprintf(stderr, " the sampling frame and click any mouse button\n"); R_get_location_with_line(0, 0, l, t, &btn); fprintf(stderr, "\n Please move cursor to the LOWER-RIGHT corner of\n"); fprintf(stderr, " the sampling frame and click any mouse button again\n"); back2: R_get_location_with_box(*l, *t, r, b, &btn); /* check that sampling frame is in map */ if (*l < l0 || *r > r0 || *t < t0 || *b > b0) { fprintf(stderr, "\n The cursor is outside of the map, try again\n"); goto back; } /* check that cursor is below & to right */ if (*r <= *l || *b <= *t) { fprintf(stderr, "\n Please put the lower right corner below and to the"); fprintf(stderr, "\n right of the upper left corner\n"); goto back2; } R_standard_color(D_translate_color("grey")); *l = (int)((double)((int)(*l * msc[0] + 0.5)) / msc[0]); *r = (int)((double)((int)(*r * msc[0] + 0.5)) / msc[0]); *t = (int)((double)((int)(*t * msc[1] + 0.5)) / msc[1]); *b = (int)((double)((int)(*b * msc[1] + 0.5)) / msc[1]); draw_box(*l, *t, *r, *b, 1); R_close_driver(); fprintf(stderr, "\n Sampling frame is set to the area you just drew"); } return; }