5
#include <grass/raster.h>
7
#include "local_proto.h"
12
int top, bottom, left, right;
16
static struct box more, less, report;
17
static int height, size, edge, nlines;
18
static int curp, first_point, i;
20
static double *xres, *yres, *gnd;
22
static int xmax, ymax, gmax;
24
static int uparrow(struct box *, int);
25
static int downarrow(struct box *, int);
26
static int pick(int, int);
27
static int done(void);
28
static int cancel_which(void);
29
static int inbox(struct box *, int, int);
30
static int dotext(char *, int, int, int, int, int, int);
31
static int compute_transformation(void);
32
static int debug(char *);
33
static int to_file(void);
34
static int askfile(void);
35
static int to_printer(void);
36
static int do_report(FILE *);
37
static int printcentered(FILE *, char *, int);
38
static int show_point(int, int);
41
sprintf (buf, "%3d ", n)
42
#define FMT1(buf,xres,yres,gnd) \
43
sprintf (buf, "%5.1f %5.1f %6.1f ", xres,yres,gnd)
44
#define LHEAD1 " error "
45
#define LHEAD2 " # east north target "
47
#define FMT2(buf,e1,n1,e2,n2,z2) \
48
sprintf (buf, "%9.1f %9.1f %9.1f %9.1f %9.1f ", e1,n1,e2,n2,z2)
49
#define RHEAD1 " image target "
50
#define RHEAD2 " east north east north elev."
52
#define BACKGROUND GREY
57
static Objects objects[] = {
58
MENU("DONE", done, &use),
59
MENU("PRINT", to_printer, &use),
60
MENU("FILE", to_file, &use),
61
INFO(" Double click on point to be included/excluded ", &use),
71
int top, bottom, left, right, width, middle, nums;
73
/* to give user a response of some sort */
74
Menu_msg("Preparing analysis ...");
77
* build a popup window at center of the screen.
78
* 35% the height and wide enough to hold the report
82
/* height of 1 line, based on NLINES taking up 35% vertical space */
83
height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1;
85
/* size of text, 80% of line height */
87
size = tsize - 2; /* fudge for computing pixels width of text */
89
/* indent for the text */
90
edge = .1 * height + 1;
92
/* determine the length, in chars, of printed line */
94
nums = strlen(buf) * size;
95
FMT1(buf, 0.0, 0.0, 0.0);
98
FMT2(buf, 0.0, 0.0, 0.0, 0.0, 0.0);
101
/* width is for max chars plus sidecar for more/less */
102
width = len * size + nums + 2 * height;
103
if ((SCREEN_RIGHT - SCREEN_LEFT) < width)
104
width = SCREEN_RIGHT - SCREEN_LEFT;
107
/* define the window */
108
bottom = VIEW_MENU->top - 1;
109
top = bottom - height * NLINES;
113
right = left + width;
114
middle += left + nums;
117
/* save what is under this area, so it can be restored */
118
R_panel_save(tempfile1, top, bottom+1, left, right+1);
121
/* fill it with white */
122
R_standard_color(BACKGROUND);
123
R_box_abs(left, top, right, bottom);
125
right -= 2 * height; /* reduce it to exclude sidecar */
127
/* print messages in message area */
128
R_text_size(tsize, tsize);
131
/* setup the more/less boxes in the sidecar */
132
R_standard_color(BLACK);
134
less.bottom = top + 2 * height;
136
less.right = right + 2 * height;
137
Outline_box(less.top, less.bottom, less.left, less.right);
139
more.top = bottom - 2 * height;
140
more.bottom = bottom;
142
more.right = right + 2 * height;
143
Outline_box(more.top, more.bottom, more.left, more.right);
146
* top two lines are for column labels
147
* last two line is for overall rms error.
152
/* allocate predicted values */
153
xres = (double *)G_calloc(group.control_points.count, sizeof(double));
154
yres = (double *)G_calloc(group.control_points.count, sizeof(double));
155
gnd = (double *)G_calloc(group.control_points.count, sizeof(double));
157
/* compute transformation for the first time */
158
compute_transformation();
161
/* put head on the report */
163
dotext(LHEAD1, cury, cury + height, left, middle, 0, BLACK);
164
dotext(RHEAD1, cury, cury + height, middle, right - 1, 0, BLACK);
166
dotext(LHEAD2, cury, cury + height, left, middle, 0, BLACK);
167
dotext(RHEAD2, cury, cury + height, middle, right - 1, 0, BLACK);
169
R_move_abs(left, cury - 1);
170
R_cont_abs(right, cury - 1);
172
/* isolate the sidecar */
173
R_move_abs(right, top);
174
R_cont_abs(right, bottom);
176
/* define report box */
179
report.right = right;
184
R_text_size(tsize, tsize);
187
cury = top + 2 * height;
189
if (line >= nlines || curp >= group.control_points.count)
192
if (group.con_equation_stat > 0 &&
193
group.control_points.status[curp] > 0) {
195
FMT1(buf, xres[curp], yres[curp], gnd[curp]);
196
if (curp == xmax || curp == ymax || curp == gmax)
198
dotext(buf, cury, cury + height, nums, middle, 0, color);
200
else if (group.control_points.status[curp] > 0)
201
dotext("?", cury, cury + height, nums, middle, 1, BLACK);
203
dotext("not used", cury, cury + height, nums, middle, 1,
207
dotext(buf, cury, cury + height, left, nums, 0, BLACK);
209
group.control_points.e1[curp],
210
group.control_points.n1[curp],
211
group.control_points.e2[curp],
212
group.control_points.n2[curp],
213
group.control_points.z2[curp]);
214
dotext(buf, cury, cury + height, middle, right - 1, 0, BLACK);
219
report.bottom = cury;
220
downarrow(&more, curp < group.control_points.count ? BLACK :
222
uparrow(&less, first_point > 0 ? BLACK : BACKGROUND);
223
R_standard_color(BACKGROUND);
224
R_box_abs(left, cury, right - 1, bottom);
225
if (group.con_equation_stat < 0) {
227
strcpy(buf, "Poorly placed control points");
229
else if (group.con_equation_stat == 0) {
231
strcpy(buf, "No active control points");
235
sprintf(buf, "Overall rms error: %.2f", rms);
237
dotext(buf, bottom - height, bottom, left, right - 1, 0, color);
238
R_standard_color(BLACK);
239
R_move_abs(left, bottom - height);
240
R_cont_abs(right - 1, bottom - height);
244
if (Input_pointer(objects) < 0)
248
/* all done. restore what was under the window */
249
right += 2 * height; /* move it back over the sidecar */
250
R_standard_color(BACKGROUND);
251
R_box_abs(left, top, right, bottom);
252
R_panel_restore(tempfile1);
253
R_panel_delete(tempfile1);
259
for (i = 0; i < group.control_points.count; i++)
260
group.control_points.status[i] = group.control_points.status[i];
261
I_put_con_points(group.name, &group.control_points);
262
display_conz_points(1);
263
return 0; /* return but don't QUIT */
266
static int uparrow(struct box *box, int color)
268
R_standard_color(color);
269
Uparrow(box->top + edge, box->bottom - edge, box->left + edge,
275
static int downarrow(struct box *box, int color)
277
R_standard_color(color);
278
Downarrow(box->top + edge, box->bottom - edge, box->left + edge,
284
static int pick(int x, int y)
291
if (inbox(&more, x, y)) {
292
if (curp >= group.control_points.count)
298
if (inbox(&less, x, y)) {
299
if (first_point == 0)
301
first_point -= nlines;
307
if (!inbox(&report, x, y)) {
311
n = (y - report.top) / height;
312
if (n == cur) { /* second click! */
313
group.control_points.status[first_point + n] =
314
!group.control_points.status[first_point + n];
315
Menu_msg("Computing equations...");
316
compute_transformation();
317
show_point(first_point + n, 1);
323
show_point(first_point + n, 0);
324
R_standard_color(RED);
325
Outline_box((report.top + n * height)+1, report.top + (n + 1) * height,
326
report.left, report.right - 1);
328
return 0; /* ignore first click */
332
static int done(void)
338
static int cancel_which(void)
341
R_standard_color(BACKGROUND);
342
Outline_box((report.top + which * height)+1,
343
report.top + (which + 1) * height, report.left,
345
show_point(first_point + which, 1);
352
static int inbox(struct box *box, int x, int y)
354
return (x > box->left && x < box->right && y > box->top &&
358
static int dotext(char *text, int top, int bottom, int left, int right,
359
int centered, int color)
361
R_standard_color(BACKGROUND);
362
R_box_abs(left, top, right, bottom);
363
R_standard_color(color);
364
R_move_abs(left + 1 + edge, bottom - 1 - edge);
366
R_move_rel((right - left - strlen(text) * size) / 2, 0);
367
R_set_window(top, bottom, left, right); /* for text clipping */
369
R_set_window(SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT);
374
static int compute_transformation(void)
377
double d, d1, d2, sum;
379
double xval, yval, gval;
381
G_debug(2, "INVERSE ORTHO:\n");
383
xmax = ymax = gmax = 0;
384
xval = yval = gval = 0.0;
386
Compute_ortho_equation();
387
if (group.con_equation_stat <= 0)
390
/* compute the row,col error plus ground error keep track of largest
391
and second largest error */
395
for (n = 0; n < group.control_points.count; n++) {
396
if (group.control_points.status[n] <= 0)
400
G_debug(2, "Photo coordinates \te1 = %f \tn1 = %f \tz2 = %f",
401
group.control_points.e1[n], group.control_points.n1[n],
402
group.control_points.z2[n]);
403
G_debug(2, "Camera \txc = %f \tyc = %f \tzc = %f",
404
group.XC, group.YC, group.ZC);
405
G_debug(2, " \tomega = %f \tphi = %f \tkappa = %f",
406
group.omega, group.phi, group.kappa);
408
I_inverse_ortho_ref(temp_points.e1[n],
413
group.XC, group.YC, group.ZC, group.MI);
416
I_inverse_ortho_ref (group.control_points.e1[n],
417
group.control_points.n1[n],
418
group.control_points.z2[n],
421
group.XC, group.YC, group.ZC,
422
group.omega, group.phi, group.kappa);
425
G_debug(2, "Ground coordinates \tx = %f \ty = %f", e1, n1);
427
d = e1 - group.control_points.e2[n];
436
d = n1 - group.control_points.n2[n];
445
/* compute target error (ie along diagonal) */
446
d1 = e1 - group.control_points.e2[n];
447
d2 = n1 - group.control_points.n2[n];
448
d = d1 * d1 + d2 * d2;
449
sum += d; /* add it to rms sum, before taking sqrt */
452
if (d > gval) { /* is this one the max? */
458
/* compute overall rms error */
460
rms = sqrt(sum / count);
465
static int debug(char *msg)
468
Curses_write_window(PROMPT_WINDOW, 1, 1, msg);
474
static int to_file(void)
480
if (Input_other(askfile, "Keyboard") < 0) {
484
fd = fopen(buf, "w");
486
sprintf(msg, "** Unable to create file %s\n", buf);
488
Curses_write_window(PROMPT_WINDOW, 2, 1, msg);
493
sprintf(msg, "Report saved in file %s\n", buf);
494
Curses_write_window(PROMPT_WINDOW, 2, 1, msg);
499
static int askfile(void)
504
Curses_prompt_gets("Enter file to hold report: ", file);
508
if (G_index(file, '/'))
511
sprintf(buf, "%s/%s", G_home(), file);
512
if (access(buf, 0) != 0)
514
sprintf(buf, "** %s already exists. choose another file", file);
516
Curses_write_window(PROMPT_WINDOW, 2, 1, buf);
522
static int to_printer(void)
527
Menu_msg("sending report to printer ...");
529
fd = popen("lpr", "w");
535
static int do_report(FILE * fd)
541
fprintf(fd, "LOCATION: %-20s GROUP: %-20s MAPSET: %s\n\n",
542
G_location(), group.name, G_mapset());
543
fprintf(fd, "%15sAnalysis of control point registration\n\n", "");
544
fprintf(fd, "%s %s\n", LHEAD1, RHEAD1);
545
fprintf(fd, "%s %s\n", LHEAD2, RHEAD2);
547
FMT1(buf, 0.0, 0.0, 0.0);
550
for (n = 0; n < group.control_points.count; n++) {
552
fprintf(fd, "%s", buf);
553
if (group.con_equation_stat > 0 && group.control_points.status[n] > 0) {
554
FMT1(buf, xres[n], yres[n], gnd[n]);
555
fprintf(fd, "%s", buf);
557
else if (group.control_points.status[n] > 0)
558
printcentered(fd, "?", width);
560
printcentered(fd, "not used", width);
562
group.control_points.e1[n],
563
group.control_points.n1[n],
564
group.control_points.e2[n],
565
group.control_points.n2[n], group.control_points.z2[n]);
566
fprintf(fd, " %s\n", buf);
569
if (group.con_equation_stat < 0)
570
fprintf(fd, "Poorly place control points\n");
571
else if (group.con_equation_stat == 0)
572
fprintf(fd, "No active control points\n");
574
fprintf(fd, "Overall rms error: %.2f\n", rms);
579
static int printcentered(FILE * fd, char *buf, int width)
586
n = (width - len) / 2;
588
for (i = 0; i < n; i++)
590
fprintf(fd, "%s", buf);
598
static int show_point(int n, int true_color)
601
R_standard_color(ORANGE);
602
else if (group.control_points.status[n])
603
R_standard_color(GREEN);
605
R_standard_color(RED);
606
display_one_point(VIEW_MAP1, group.control_points.e1[n],
607
group.control_points.n1[n]);