main.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /****************************************************************************
  2. *
  3. * MODULE: v.rectify
  4. * AUTHOR(S): Markus Metz
  5. * based on i.rectify
  6. * PURPOSE: calculate a transformation matrix and then convert x,y(,z)
  7. * coordinates to standard map coordinates for all objects in
  8. * the vector
  9. * control points can come from g.gui.gcp or
  10. * a user-given text file
  11. * COPYRIGHT: (C) 2002-2011 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <grass/gis.h>
  22. #include <grass/imagery.h>
  23. #include <grass/vector.h>
  24. #include <grass/glocale.h>
  25. #include "global.h"
  26. #include "crs.h"
  27. /* georef coefficients */
  28. double E12[20], N12[20], Z12[20];
  29. double E21[20], N21[20], Z21[20];
  30. double HG12[20], HG21[20], HQ12[20], HQ21[20];
  31. double OR12[20], OR21[20];
  32. int main(int argc, char *argv[])
  33. {
  34. char group[INAME_LEN];
  35. int order, orthorot;
  36. int n, i, nlines, type;
  37. int target_overwrite = 0;
  38. char *points_file, *overstr, *rms_sep;
  39. struct Map_info In, Out;
  40. struct line_pnts *Points, *OPoints;
  41. struct line_cats *Cats;
  42. double x, y, z;
  43. int use3d;
  44. FILE *fp;
  45. struct Option *grp, /* imagery group */
  46. *val, /* transformation order */
  47. *in_opt, /* input vector name */
  48. *out_opt, /* output vector name */
  49. *pfile, /* text file with GCPs */
  50. *rfile, /* text file to hold RMS errors */
  51. *sep; /* field separator for RMS report */
  52. struct Flag *flag_use3d, *no_topo, *print_rms, *ortho;
  53. struct GModule *module;
  54. G_gisinit(argv[0]);
  55. module = G_define_module();
  56. G_add_keyword(_("vector"));
  57. G_add_keyword(_("rectify"));
  58. module->description =
  59. _("Rectifies a vector by computing a coordinate "
  60. "transformation for each object in the vector based on the "
  61. "control points.");
  62. in_opt = G_define_standard_option(G_OPT_V_INPUT);
  63. in_opt->required = YES;
  64. out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
  65. out_opt->required = YES;
  66. grp = G_define_standard_option(G_OPT_I_GROUP);
  67. grp->required = NO;
  68. pfile = G_define_standard_option(G_OPT_F_INPUT);
  69. pfile->key = "points";
  70. pfile->description = _("Name of input file with control points");
  71. pfile->required = NO;
  72. rfile = G_define_standard_option(G_OPT_F_INPUT);
  73. rfile->key = "rmsfile";
  74. rfile->description = _("Name of output file with RMS errors (if omitted or '-' output to stdout");
  75. rfile->required = NO;
  76. val = G_define_option();
  77. val->key = "order";
  78. val->type = TYPE_INTEGER;
  79. val->required = NO;
  80. val->options = "1-3";
  81. val->answer = "1";
  82. val->description = _("Rectification polynomial order (1-3)");
  83. sep = G_define_standard_option(G_OPT_F_SEP);
  84. sep->label = _("Field separator for RMS report");
  85. flag_use3d = G_define_flag();
  86. flag_use3d->key = '3';
  87. flag_use3d->description = _("Perform 3D transformation");
  88. ortho = G_define_flag();
  89. ortho->key = 'o';
  90. ortho->description = _("Perform orthogonal 3D transformation");
  91. print_rms = G_define_flag();
  92. print_rms->key = 'r';
  93. print_rms->label = _("Print RMS errors");
  94. print_rms->description = _("Print RMS errors and exit without rectifying the input map");
  95. no_topo = G_define_standard_flag(G_FLG_V_TOPO);
  96. if (G_parser(argc, argv))
  97. exit(EXIT_FAILURE);
  98. if (grp->answer) {
  99. G_strip(grp->answer);
  100. strcpy(group, grp->answer);
  101. }
  102. else
  103. group[0] = '\0';
  104. points_file = pfile->answer;
  105. if (grp->answer == NULL && points_file == NULL)
  106. G_fatal_error(_("Please select a group or give an input file."));
  107. else if (grp->answer != NULL && points_file != NULL)
  108. G_warning(_("Points in group will be ignored, GCPs in input file are used."));
  109. order = atoi(val->answer);
  110. if (order < 1 || order > MAXORDER)
  111. G_fatal_error(_("Invalid order (%d); please enter 1 to %d"), order,
  112. MAXORDER);
  113. Vect_set_open_level(1);
  114. if (Vect_open_old2(&In, in_opt->answer, "", "") < 0)
  115. G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);
  116. use3d = (Vect_is_3d(&In) &&
  117. (flag_use3d->answer || ortho->answer));
  118. if (!use3d && (flag_use3d->answer || ortho->answer))
  119. G_fatal_error(_("3D transformation requires a 3D vector"));
  120. if (use3d && !points_file)
  121. G_fatal_error(_("A file with 3D control points is needed for 3D transformation"));
  122. orthorot = ortho->answer;
  123. if (print_rms->answer)
  124. rms_sep = G_option_to_separator(sep);
  125. else
  126. rms_sep = NULL;
  127. if (rfile->answer) {
  128. if (strcmp(rfile->answer, "-")) {
  129. fp = fopen(rfile->answer, "w");
  130. if (!fp)
  131. G_fatal_error(_("Unable to open file '%s' for writing"),
  132. rfile->answer);
  133. }
  134. else
  135. fp = stdout;
  136. }
  137. else
  138. fp = stdout;
  139. /* read the control points for the group */
  140. get_control_points(group, points_file, order, use3d, orthorot,
  141. print_rms->answer, rms_sep, fp);
  142. if (print_rms->answer) {
  143. Vect_close(&In);
  144. exit(EXIT_SUCCESS);
  145. }
  146. /* get the target */
  147. get_target(group);
  148. /* Check the GRASS_OVERWRITE environment variable */
  149. if ((overstr = getenv("GRASS_OVERWRITE"))) /* OK ? */
  150. target_overwrite = atoi(overstr);
  151. if (!target_overwrite) {
  152. /* check if output exists in target location/mapset */
  153. select_target_env();
  154. if (G_find_vector2(out_opt->answer, G_mapset())) {
  155. G_warning(_("The vector map <%s> already exists in"), out_opt->answer);
  156. G_warning(_("target LOCATION %s, MAPSET %s:"),
  157. G_location(), G_mapset());
  158. G_fatal_error(_("Rectification cancelled."));
  159. }
  160. select_current_env();
  161. }
  162. else
  163. G_debug(1, "Overwriting OK");
  164. select_target_env();
  165. if (Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In)) < 0)
  166. G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
  167. Vect_copy_head_data(&In, &Out);
  168. Vect_hist_copy(&In, &Out);
  169. Vect_hist_command(&Out);
  170. select_current_env();
  171. Points = Vect_new_line_struct();
  172. OPoints = Vect_new_line_struct();
  173. Cats = Vect_new_cats_struct();
  174. /* count lines */
  175. nlines = 0;
  176. while (1) {
  177. type = Vect_read_next_line(&In, Points, Cats);
  178. if (type == 0)
  179. continue; /* Dead */
  180. if (type == -1)
  181. G_fatal_error(_("Reading input vector map"));
  182. if (type == -2)
  183. break;
  184. nlines++;
  185. }
  186. Vect_rewind(&In);
  187. i = 0;
  188. z = 0.0;
  189. while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
  190. G_percent(i++, nlines, 4);
  191. Vect_reset_line(OPoints);
  192. for (n = 0; n < Vect_get_num_line_points(Points); n++) {
  193. if (use3d) {
  194. if (orthorot)
  195. CRS_georef_or(Points->x[n], Points->y[n], Points->z[n],
  196. &x, &y, &z, OR12);
  197. else
  198. CRS_georef_3d(Points->x[n], Points->y[n], Points->z[n],
  199. &x, &y, &z, E12, N12, Z12, order);
  200. }
  201. else {
  202. I_georef(Points->x[n], Points->y[n],
  203. &x, &y, E12, N12, order);
  204. z = Points->z[n];
  205. }
  206. Vect_append_point(OPoints, x, y, z);
  207. }
  208. select_target_env();
  209. Vect_write_line(&Out, type, OPoints, Cats);
  210. select_current_env();
  211. }
  212. G_percent(1, 1, 1);
  213. select_target_env();
  214. if (!no_topo->answer)
  215. Vect_build(&Out);
  216. /* Copy tables */
  217. G_message(_("Copying attribute table(s)..."));
  218. if (Vect_copy_tables(&In, &Out, 0))
  219. G_warning(_("Failed to copy attribute table to output map"));
  220. Vect_close(&Out);
  221. select_current_env();
  222. Vect_close(&In);
  223. G_done_msg(" ");
  224. exit(EXIT_SUCCESS);
  225. }