int delete_control_point(int n) { int i; char msg[80]; if ((n < 0) | (n > group.points.count - 1)) { sprintf(msg, "%d is an invalid control point index value.", n); G_warning(msg); return 1; } for (i = n; i < group.points.count - 1; i++) { G_copy(&group.points.e1[i], &group.points.e1[i + 1], sizeof(group.points.e1[0])); G_copy(&group.points.n1[i], &group.points.n1[i + 1], sizeof(group.points.n1[0])); G_copy(&group.points.e2[i], &group.points.e2[i + 1], sizeof(group.points.e2[0])); G_copy(&group.points.n2[i], &group.points.n2[i + 1], sizeof(group.points.n2[0])); G_copy(&group.points.status[i], &group.points.status[i + 1], sizeof(group.points.status[0])); } group.points.count -= 1; if (I_put_control_points(group.name, &group.points) < 0) { G_fatal_error("bad return on I_put_control_points"); return 1; } return 0; }
int analyze(void) { static int use = 1; static Objects objects[] = { MENU("DONE", done, &use), MENU("PRINT", to_printer, &use), MENU("FILE", to_file, &use), MENU("OVERLAY", do_warp, &use), MENU(delete_msg, delete_mark, &use), INFO("Transform->", &use), MENU(order_msg, get_order, &use), INFO(pick_msg, &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 (!delete_mode) color = BLACK; else color = BLUE; 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, color); else dotext("not used", cury, cury + height, nums, middle, 1, color); if (pager) { FMT0(buf, curp + 1); dotext(buf, cury, cury + height, left, nums, 0, color); 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, color); } cury += height; curp++; } report.bottom = cury; downarrow(&more, curp < group.points.count ? color : BACKGROUND); uparrow(&less, first_point > 0 ? color : BACKGROUND); R_standard_color(BACKGROUND); R_box_abs(left, cury, right - 1, bottom); if (group.equation_stat < 0) { if (group.equation_stat == -1) { color = RED; strcpy(buf, "Poorly placed control points"); } else { if (group.equation_stat == -2) G_fatal_error("NOT ENOUGH MEMORY"); else G_fatal_error("PARAMETER ERROR"); } } 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; display_points(1); } /* 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 */ }
int main(int argc, char **argv) { struct Option *grp, *val, *fmt, *xfm_pts; struct Flag *sum, *rev_flag, *dump_flag; struct GModule *module; char *desc; G_gisinit(argv[0]); /* Get Args */ module = G_define_module(); G_add_keyword(_("miscellaneous")); G_add_keyword(_("transformation")); G_add_keyword("GCP"); module->description = _("Computes a coordinate transformation based on the control points."); grp = G_define_standard_option(G_OPT_I_GROUP); val = G_define_option(); val->key = "order"; val->type = TYPE_INTEGER; val->required = YES; val->options = "1-3"; val->description = _("Rectification polynomial order"); fmt = G_define_option(); fmt->key = "format"; fmt->type = TYPE_STRING; fmt->required = NO; fmt->multiple = YES; fmt->options = "idx,src,dst,fwd,rev,fxy,rxy,fd,rd"; desc = NULL; G_asprintf(&desc, "idx;%s;src;%s;dst;%s;fwd;%s;rev;%s;fxy;%s;rxy;%s;fd;%s;rd;%s", _("point index"), _("source coordinates"), _("destination coordinates"), _("forward coordinates (destination)"), _("reverse coordinates (source)"), _("forward coordinates difference (destination)"), _("reverse coordinates difference (source)"), _("forward error (destination)"), _("reverse error (source)")); fmt->descriptions = desc; fmt->answer = "fd,rd"; fmt->description = _("Output format"); sum = G_define_flag(); sum->key = 's'; sum->description = _("Display summary information"); xfm_pts = G_define_standard_option(G_OPT_F_INPUT); xfm_pts->required = NO; xfm_pts->label = _("File containing coordinates to transform (\"-\" to read from stdin)"); xfm_pts->description = _("Local x,y coordinates to target east,north"); rev_flag = G_define_flag(); rev_flag->key = 'r'; rev_flag->label = _("Reverse transform of coords file or coeff. dump"); rev_flag->description = _("Target east,north coordinates to local x,y"); dump_flag = G_define_flag(); dump_flag->key = 'x'; dump_flag->description = _("Display transform matrix coefficients"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); name = grp->answer; order = atoi(val->answer); summary = !!sum->answer; columns = fmt->answers; forward = !rev_flag->answer; coord_file = xfm_pts->answer; I_get_control_points(name, &points); parse_format(); compute_transformation(); I_put_control_points(name, &points); analyze(); if(dump_flag->answer) dump_cooefs(); if(coord_file) do_pt_xforms(); return 0; }