#include #include #include #include #include #include #include "globals.h" #include "local_proto.h" #define NLINES 18 struct box { int top, bottom, left,right; }; static int uparrow ( struct box *,int); static int downarrow ( struct box *,int) ; static int pick(int,int); static int done(void); static int cancel_which(void); static int inbox (struct box *,int,int); static int dotext (char *,int,int,int,int,int,int); static int compute_transformation(void); static int to_file(void); static int askfile(void); static int to_printer(void); static int do_report ( FILE *); static int printcentered(FILE *,char *,int); static int show_point(int,int); static int which; static struct box more, less, report; static int height, size, edge, nlines; static int curp, first_point; static double rms; static double *xres, *yres, *gnd; static int pager; static int xmax, ymax, gmax; static char buf[300]; #define FMT0(buf,n) \ sprintf (buf, "%3d ", n) #define FMT1(buf,xres,yres,gnd) \ sprintf (buf, "%5.1f %5.1f %6.1f ", xres,yres,gnd) #define LHEAD1 " error " #define LHEAD2 " # col row target" #define FMT2(buf,e1,n1,e2,n2) \ sprintf (buf, "%9.1f %9.1f %9.1f %9.1f ", e1,n1,e2,n2) #define RHEAD1 " image target" #define RHEAD2 " east north east north" #define BACKGROUND GREY int analyze (void) { static int use = 1; static Objects objects[]= { MENU("DONE", done, &use), MENU("PRINT", to_printer, &use), MENU("FILE", to_file, &use), INFO(" Double click on point to be included/excluded ", &use), OTHER(pick,&use), {0} }; int color; int tsize; int cury; int len; int line; int top, bottom, left, right, width, middle, nums; /* to give user a response of some sort */ Menu_msg ("Preparing analysis ..."); /* * build a popup window at center of the screen. * 35% the height and wide enough to hold the report * */ /* height of 1 line, based on NLINES taking up 35% vertical space */ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP))/NLINES + 1; /* size of text, 80% of line height */ tsize = .8 * height; size = tsize-2; /* fudge for computing pixels width of text */ /* indent for the text */ edge = .1 * height + 1; /* determine the length, in chars, of printed line */ FMT0 (buf,0); nums = strlen(buf) * size; FMT1 (buf, 0.0, 0.0, 0.0); len = strlen(buf); middle = len * size; FMT2 (buf, 0.0, 0.0, 0.0, 0.0); len += strlen(buf) ; /* width is for max chars plus sidecar for more/less */ width = len * size + nums + 2*height; if ((SCREEN_RIGHT - SCREEN_LEFT) < width) width = SCREEN_RIGHT - SCREEN_LEFT; /* define the window */ bottom = VIEW_MENU->top-1; top = bottom - height*NLINES; left = SCREEN_LEFT; right = left + width; middle += left + nums; nums += left; /* save what is under this area, so it can be restored */ R_panel_save (tempfile1, top, bottom+1, left, right+1); /* fill it with white */ R_standard_color (BACKGROUND); R_box_abs (left, top, right, bottom); right -= 2*height; /* reduce it to exclude sidecar */ /* print messages in message area */ R_text_size (tsize, tsize); /* setup the more/less boxes in the sidecar */ R_standard_color (BLACK); less.top = top; less.bottom = top + 2*height; less.left = right; less.right = right + 2*height; Outline_box (less.top, less.bottom, less.left, less.right); more.top = bottom - 2*height; more.bottom = bottom; more.left = right; more.right = right + 2*height; Outline_box (more.top, more.bottom, more.left, more.right); /* * top two lines are for column labels * last two line is for overall rms error. */ nlines = NLINES - 3; first_point = 0; /* allocate predicted values */ xres = (double *) G_calloc (group.points.count, sizeof (double)); yres = (double *) G_calloc (group.points.count, sizeof (double)); gnd = (double *) G_calloc (group.points.count, sizeof (double)); /* compute transformation for the first time */ compute_transformation(); /* put head on the report */ cury = top; dotext (LHEAD1, cury, cury+height, left, middle, 0, BLACK); dotext (RHEAD1, cury, cury+height, middle, right-1, 0, BLACK); cury += height; dotext (LHEAD2, cury, cury+height, left, middle, 0, BLACK); dotext (RHEAD2, cury, cury+height, middle, right-1, 0, BLACK); cury += height; R_move_abs (left, cury-1); R_cont_abs (right, cury-1); /* isolate the sidecar */ R_move_abs (right, top); R_cont_abs (right, bottom); /* define report box */ report.top = cury; report.left = left; report.right = right; /* lets do it */ pager = 1; while(1) { R_text_size (tsize, tsize); line = 0; curp = first_point; cury = top + 2*height; while(1) { if (line >= nlines || curp >= group.points.count) break; line++; if(group.equation_stat > 0 && group.points.status[curp] > 0) { color = BLACK; FMT1(buf, xres[curp], yres[curp], gnd[curp]); if (curp == xmax || curp == ymax || curp == gmax) color = RED; dotext (buf, cury, cury+height, nums, middle, 0, color); } else if (group.points.status[curp] > 0) dotext ("?", cury, cury+height, nums, middle, 1, BLACK); else dotext ("not used", cury, cury+height, nums, middle, 1, BLACK); if (pager) { FMT0 (buf, curp+1); dotext (buf, cury, cury+height, left, nums, 0, BLACK); FMT2(buf, group.points.e1[curp], group.points.n1[curp], group.points.e2[curp], group.points.n2[curp]); dotext (buf, cury, cury+height, middle, right-1, 0, BLACK); } cury += height; curp++; } report.bottom = cury; downarrow (&more, curp < group.points.count ? BLACK : BACKGROUND); uparrow (&less, first_point > 0 ? BLACK : BACKGROUND); R_standard_color (BACKGROUND); R_box_abs (left, cury, right-1, bottom); if (group.equation_stat < 0) { color = RED; strcpy (buf, "Poorly placed control points"); } else if (group.equation_stat == 0) { color = RED; strcpy (buf, "No active control points"); } else { color = BLACK; sprintf (buf, "Overall rms error: %.2f", rms); } dotext (buf, bottom-height, bottom, left, right-1, 0, color); R_standard_color (BLACK); R_move_abs (left, bottom-height); R_cont_abs (right-1, bottom-height); pager = 0; which = -1; if(Input_pointer(objects) < 0) break; } /* all done. restore what was under the window */ right += 2*height; /* move it back over the sidecar */ R_standard_color (BACKGROUND); R_box_abs (left, top, right, bottom); R_panel_restore (tempfile1); R_panel_delete (tempfile1); R_flush(); G_free (xres); G_free (yres); G_free (gnd); I_put_control_points (group.name, &group.points); display_points(1); return 0; /* return but don't QUIT */ } static int uparrow (struct box *box, int color) { R_standard_color (color); Uparrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge); return 0; } static int downarrow(struct box *box, int color) { R_standard_color (color); Downarrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge); return 0; } static int pick(int x,int y) { int n; int cur; cur = which; cancel_which(); if (inbox(&more,x,y)) { if (curp >= group.points.count) return 0; first_point = curp; pager = 1; return 1; } if (inbox(&less,x,y)) { if (first_point == 0) return 0; first_point -= nlines; if (first_point < 0) first_point = 0; pager = 1; return 1; } if (!inbox (&report,x,y)) { return 0; } n = (y - report.top)/height; if (n == cur) /* second click! */ { group.points.status[first_point+n] = !group.points.status[first_point+n]; compute_transformation(); show_point (first_point+n, 1); return 1; } /* first click */ which = n; show_point (first_point+n, 0); R_standard_color (RED); Outline_box ((report.top + n*height)+1, report.top +(n+1)*height, report.left, report.right-1); R_flush(); return 0; /* ignore first click */ } static int done (void) { cancel_which(); return -1; } static int cancel_which (void) { if (which >= 0) { R_standard_color (BACKGROUND); Outline_box ((report.top + which*height)+1, report.top +(which+1)*height, report.left, report.right-1); show_point (first_point+which, 1); } which = -1; return 0; } static int inbox (struct box *box,int x,int y) { return (x>box->left && x right && y>box->top && ybottom); } static int dotext (char *text, int top,int bottom,int left,int right,int centered,int color) { R_standard_color (BACKGROUND); R_box_abs (left, top, right, bottom); R_standard_color (color); R_move_abs (left+1+edge, bottom-1-edge); if (centered) R_move_rel ((right-left-strlen(text)*size)/2,0); R_set_window (top, bottom, left, right); /* for text clipping */ R_text (text); R_set_window (SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT); return 0; } static int compute_transformation (void) { int n, count; double d,d1,d2,sum; double e1, e2, n1, n2; double xval, yval, gval; xmax = ymax = gmax = 0; xval = yval = gval = 0.0; Compute_equation(); if (group.equation_stat <= 0) return 1; /* compute the row,col error plus ground error * keep track of largest and second largest error */ sum = 0.0; rms = 0.0; count = 0; for (n = 0; n < group.points.count; n++) { if (group.points.status[n] <= 0) continue; count++; I_georef (group.points.e2[n], group.points.n2[n], &e1, &n1, group.E21, group.N21); I_georef (group.points.e1[n], group.points.n1[n], &e2, &n2, group.E12, group.N12); if((d = xres[n] = e1-group.points.e1[n]) < 0) d = -d; if (d > xval) { xmax = n; xval = d; } if ((d = yres[n] = n1-group.points.n1[n]) < 0) d = -d; if (d > yval) { ymax = n; yval = d; } /* compute ground error (ie along diagonal) */ d1 = e2 - group.points.e2[n]; d2 = n2 - group.points.n2[n]; d = d1*d1 + d2*d2; sum += d; /* add it to rms sum, before taking sqrt */ d = sqrt(d); gnd[n] = d; if (d > gval) /* is this one the max? */ { gmax = n; gval = d; } } /* compute overall rms error */ if (count) rms = sqrt (sum/count); return 0; } static int to_file (void) { FILE *fd; char msg[1024]; cancel_which(); if (Input_other (askfile, "Keyboard") < 0) { return 0; } fd = fopen (buf, "w"); if (fd == NULL) { sprintf (msg, "** Unable to create file %s\n", buf); Beep(); Curses_write_window (PROMPT_WINDOW, 2, 1, msg); } else { do_report (fd); fclose (fd); sprintf (msg, "Report saved in file %s\n", buf); Curses_write_window (PROMPT_WINDOW, 2, 1, msg); } return 0; } static int askfile (void) { char file[GNAME_MAX]; while (1) { Curses_prompt_gets ("Enter file to hold report: ", file); G_strip (file); if (*file == 0) return -1; if (G_index (file, '/')) strcpy (buf, file); else sprintf (buf, "%s/%s", G_home(), file); if (access (buf, 0) != 0) return 1; sprintf (buf, "** %s already exists. choose another file", file); Beep(); Curses_write_window (PROMPT_WINDOW, 2, 1, buf); } return 0; } static int to_printer (void) { FILE *fd; cancel_which(); Menu_msg ("sending report to printer ..."); fd = popen ("lpr", "w"); do_report (fd); pclose (fd); return 0; } static int do_report ( FILE *fd) { char buf[GNAME_MAX]; int n; int width; fprintf (fd, "LOCATION: %-20s GROUP: %-20s MAPSET: %s\n\n", G_location(), group.name, G_mapset()); fprintf (fd, "%15sAnalysis of control point registration\n\n", ""); fprintf (fd, "%s %s\n", LHEAD1, RHEAD1); fprintf (fd, "%s %s\n", LHEAD2, RHEAD2); FMT1 (buf,0.0,0.0,0.0); width = strlen (buf); for (n = 0; n < group.points.count; n++) { FMT0(buf,n+1); fprintf (fd, "%s", buf); if(group.equation_stat > 0 && group.points.status[n] > 0) { FMT1(buf, xres[n], yres[n], gnd[n]); fprintf (fd, "%s", buf); } else if (group.points.status[n] > 0) printcentered (fd, "?", width); else printcentered (fd, "not used", width); FMT2(buf, group.points.e1[n], group.points.n1[n], group.points.e2[n], group.points.n2[n]); fprintf (fd, " %s\n", buf); } fprintf (fd, "\n"); if (group.equation_stat < 0) fprintf (fd, "Poorly place control points\n"); else if (group.equation_stat == 0) fprintf (fd, "No active control points\n"); else fprintf (fd, "Overall rms error: %.2f\n", rms); return 0; } static int printcentered (FILE *fd, char *buf,int width) { int len; int n; int i; len = strlen (buf); n = (width -len)/2; for (i = 0; i < n; i++) fprintf (fd, " "); fprintf (fd, "%s", buf); i += len; while (i++ < width) fprintf (fd, " "); return 0; } static int show_point(int n,int true_color) { if (!true_color) R_standard_color (ORANGE); else if(group.points.status[n]) R_standard_color (GREEN); else R_standard_color (RED); display_one_point (VIEW_MAP1, group.points.e1[n], group.points.n1[n]); return 0; }