/* $Id: edit.c,v 2.2 2006/06/29 02:40:49 cho Exp $ * * Chris Rewerts, Agricultural Engineering, Purdue University April 1991 * * The material here based originally on Dwhat. Idea is to allow user to mouse * on a cell layer on the graphics window, and we figure out which location * (row and col) in the cell file corresponds to the location clicked on the * screen. We find "real" row and col based on the cellhd window, to allow * for the displayed cell map to be in any given "current" window. * * December 1993 Chris Rewerts, CERL, Made changes in the method to check the * current region against that of the original map's header. * */ #include #include #include "edit.h" #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) int edit(void) { char string[10], val_str[100], val_str1[100], val_str2[100]; char line[128]; int num_ok; int t, b, l, r; int select_count = 0; int i; int row = 0, col = 0, real_row = 0, real_col = 0; DCELL *buf, c, num; struct Cell_head edit_window; int screen_x, screen_y; double east, north; int button; int fd; int red, green, blue; int D_y, D_x; double D_ew, D_ns; double D_north, D_south, D_east, D_west; double x1, y1, x2, y2; double edit_win_ewdist, edit_win_nsdist; double real_win_ewdist, real_win_nsdist; double pct_ewdiff, pct_nsdiff; sprintf(val_str1, "%.10f", min_value); sprintf(val_str2, "%.10f", max_value); G_trim_decimal(val_str1); G_trim_decimal(val_str2); fd = G_open_cell_old(current_name, current_mapset); if (fd < 0) { sprintf(line, "unable to open [%s] in [%s]\n", current_name, current_mapset); error(1, line); } G__get_window(&edit_window, "", "WIND", user_mapset); /* * set the window to the user's current region, and do test to check * the ns & ew distance of resolution in meters we use G_distance to * give us the meters from points plus the resolution (for ew and * ns). */ G_set_window(&edit_window); x1 = edit_window.west; x2 = edit_window.west + edit_window.ew_res; y1 = edit_window.south; y2 = edit_window.south + edit_window.ns_res; edit_win_ewdist = G_distance(x1, y1, x2, y1); edit_win_nsdist = G_distance(x1, y1, x1, y2); /* * now set the window to the map's header, and do test to check the * distance of resolution in meters */ G_set_window(&real_window); x1 = real_window.west; x2 = real_window.west + real_window.ew_res; y1 = real_window.south; y2 = real_window.south + real_window.ns_res; real_win_ewdist = G_distance(x1, y1, x2, y1); real_win_nsdist = G_distance(x1, y1, x1, y2); /* * now see if the difference is significant enough to munge what we * have to do in the point/click/edit process. for both ns and ew, we * calc the percent difference between the real (cellhd) window and * the current (edit) window meters of distance we found. our * arbitrary cutoff is 1 percent */ pct_ewdiff = ((MAX(real_win_ewdist, edit_win_ewdist) / MIN(real_win_ewdist, edit_win_ewdist)) * 100) - 100; pct_nsdiff = ((MAX(real_win_nsdist, edit_win_nsdist) / MIN(real_win_nsdist, edit_win_nsdist)) * 100) - 100; /* fprintf (stdout,"\new: %.20f%%\n", pct_ewdiff); fprintf (stdout,"\nns: %.20f%%\n", pct_nsdiff); */ /* set window back to the edit window */ G_set_window(&edit_window); /* * check to make sure that the current resolution matches the * resolution according to that we read from the cell header by * comparing the percentage difference we just calculated */ if ((pct_ewdiff > 1.0) || (pct_nsdiff > 1.0)) { error(1, "current window resolution does not match cell layer's resolution"); } if (D_check_map_window(&edit_window)) error(1, "unable to set graphics window"); /* Determine conversion factors */ if (D_get_screen_window(&t, &b, &l, &r)) error(1, "Getting graphics window coordinates"); if (D_do_conversions(&edit_window, t, b, l, r)) error(1, "Error in calculating conversions"); if (G_read_cats(current_name, current_mapset, &cats) < 0) { fprintf(stderr, "could not read cats for [%s]\n", current_name); } draw_grid(); buf = G_allocate_d_raster_buf(); screen_x = ((int) D_get_d_west() + (int) D_get_d_east()) / 2; screen_y = ((int) D_get_d_north() + (int) D_get_d_south()) / 2; /* * info needed to draw over an edited cell with the color of the new * cat */ D_east = D_get_d_east(); D_west = D_get_d_west(); D_north = D_get_d_north(); D_south = D_get_d_south(); /* how many screen distance units for each cell */ D_ew = (D_east - D_west) / edit_window.cols; D_ns = (D_south - D_north) / edit_window.rows; /* * edit mode - taking commands from mouse key presses at locations on * the graphic monitor */ edit_mouse_info(); c = num = 0.; while (1) { /* find our the screen x,y location of mouse click */ R_get_location_with_pointer(&screen_x, &screen_y, &button); if (select_count > 12) { edit_mouse_info(); select_count = 2; } /* right key means quit edit mode */ if (button == 3) { G_close_cell(fd); break; } /* if left or middle key, find out what's there */ if (button == 1 || button == 2) { /* convert display coords to UTM coords */ east = D_d_to_u_col((double) screen_x); north = D_d_to_u_row((double) screen_y); /* find out what row and col for current window */ row = (edit_window.north - north) / edit_window.ns_res; col = (east - edit_window.west) / edit_window.ew_res; /* * find out what row and col this is in the cell * layer as a whole */ real_row = (real_window.north - north) / real_window.ns_res; real_col = (east - real_window.west) / real_window.ew_res; /* * check to see if we are in the current window on * the screen i.e. there is a cell actually displayed * where they clicked */ if (east < edit_window.west || east > edit_window.east || north < edit_window.south || north > edit_window.north) { error(0, "Selection off current screen window.\n"); continue; } /* * check to see if we are within the area of the * window described by the cell header (the "real * window") */ if (east < real_window.west || east > real_window.east || north < real_window.south || north > real_window.north) { error(0, "Selection off map's window.\n"); continue; } /* find out what value is currently in that cell */ if (G_get_d_raster_row(fd, buf, row) < 0) error(1, "could not get values for selected map row"); if(G_is_d_null_value(&buf[col])) sprintf(val_str, "%s", "Null"); else { sprintf(val_str, "%.10f", buf[col]); G_trim_decimal(val_str); } fprintf (stdout,"\nCurrent value for the selected cell: %s\n", val_str); fprintf (stdout,"%s\n", G_get_d_raster_cat(&buf[col], &cats)); } /* middle button means we want to edit that cell */ if (button == 2) { int tmpx, tmpy; edit_mouse_info2(c, buf[col]); R_get_location_with_pointer(&tmpx, &tmpy, &button); if (button == 3) while (1) { /* * get new value from user, make sure * it is a number within the range of * the current cats */ fprintf (stdout,"\n\n Enter new cell value (N for null) -> "); G_gets(string); /* error check the user's input */ num_ok = 1; if(strcmp(string, "N")==0) G_set_d_null_value(&num, 1); else { if ((!isdigit(string[0])) && (string[0] != '-') && !(map_type!=CELL_TYPE && string[0]=='.')) num_ok = 0; for (i = 1; i < strlen(string); i++) { if (!isdigit(string[i]) && !(map_type!=CELL_TYPE && string[i]=='.')) num_ok = 0; } if (!num_ok) { sprintf(line, "enter %s value between %s and %s\n", (map_type==CELL_TYPE)? "an integer":"a", val_str1, val_str2); error(0, line); continue; } sscanf(string, "%lf", &num); if ((num < min_value) || (num > max_value)) { sprintf(line, "enter %s value between %s and %s\n", (map_type==CELL_TYPE)? "an integer":"a", val_str1, val_str2); error(0, line); continue; } } break; } if (button == 2 || button == 3) { select_count = 2; c = num; do_edit(real_row, real_col, c); change_made = 1; /* * type mismatch calls to the color routine, * may not work on all compilers */ G_get_d_raster_color(&c, &red, &green, &blue, &colr); R_RGB_color(red, green, blue); D_y = (int)(0.5+(row * D_ns + D_north)); D_x = (int)(0.5+(col * D_ew + D_west)); /* draw filled box */ R_box_abs(D_x+1, D_y+1, (D_x + (int)(0.5+D_ew)), (D_y + (int)(0.5+D_ns))); /* draw cleanup frame */ R_move_abs(D_x, D_y); R_standard_color(grid_color); R_cont_rel(0, (int)(0.5+D_ns)); R_cont_rel((int)(0.5+D_ew), 0); R_cont_rel(0, -1*(int)(0.5+D_ns)); R_cont_rel(-1*(int)(0.5+D_ew), 0); /* draw "X" */ R_standard_color(grid_color); R_move_abs(D_x + (int)(D_ew*0.2), D_y + (int)(D_ns*0.2)); R_cont_rel((int)(D_ew*0.6), (int)(D_ns*0.6)); R_move_rel(0, (int)(D_ns*-0.6)); R_cont_rel((int)(D_ew*-0.6), (int)(D_ns*0.6)); R_stabilize(); } edit_mouse_info(); } } return 0; } int edit_mouse_info (void) { G_clear_screen(); fprintf(stderr, "\n +--------EDIT MODE mouse button menu--------+\n"); fprintf(stderr, " | Use mouse on graphics monitor |\n"); fprintf(stderr, " | |\n"); fprintf(stderr, " |left button: What's here? |\n"); fprintf(stderr, " |middle button: Edit cell value |\n"); fprintf(stderr, " |right button: Quit edit mode |\n"); fprintf(stderr, " +-------------------------------------------+\n\n"); return 0; } int edit_mouse_info2(DCELL def,DCELL current) { char cur_str[100], def_str[100]; DCELL tmp; G_clear_screen(); tmp = current; if(G_is_d_null_value(&tmp)) sprintf(cur_str, "Null"); else { sprintf(cur_str, "%.10f", current); G_trim_decimal(cur_str); } tmp = def; if(G_is_d_null_value(&tmp)) sprintf(def_str, "Null"); else { sprintf(def_str, "%.10f", def); G_trim_decimal(def_str); } fprintf(stderr, "\n +----------Select value button menu---------+\n"); fprintf(stderr, " | Use mouse on graphics monitor |\n"); fprintf(stderr, " | |\n"); fprintf(stderr, " | Current value: %5s |\n", cur_str); fprintf(stderr, " | |\n"); fprintf(stderr, " |left button: Cancel |\n"); fprintf(stderr, " |middle button: Use value %5s? |\n", def_str); fprintf(stderr, " |right button: Select new value |\n"); fprintf(stderr, " +-------------------------------------------+\n\n"); return 0; } int use_mouse (void) { G_clear_screen(); fprintf(stderr, "\n +-------------------------------------------+\n"); fprintf(stderr, " | Use mouse on graphics monitor |\n"); fprintf(stderr, " | to make selection on the menu |\n"); fprintf(stderr, " +-------------------------------------------+\n\n"); return 0; }