main.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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. G_add_keyword(_("level1"));
  59. module->description =
  60. _("Rectifies a vector by computing a coordinate "
  61. "transformation for each object in the vector based on the "
  62. "control points.");
  63. in_opt = G_define_standard_option(G_OPT_V_INPUT);
  64. in_opt->required = YES;
  65. out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
  66. out_opt->required = YES;
  67. grp = G_define_standard_option(G_OPT_I_GROUP);
  68. grp->required = NO;
  69. pfile = G_define_standard_option(G_OPT_F_INPUT);
  70. pfile->key = "points";
  71. pfile->description = _("Name of input file with control points");
  72. pfile->required = NO;
  73. rfile = G_define_standard_option(G_OPT_F_INPUT);
  74. rfile->key = "rmsfile";
  75. rfile->description = _("Name of output file with RMS errors (if omitted or '-' output to stdout");
  76. rfile->required = NO;
  77. val = G_define_option();
  78. val->key = "order";
  79. val->type = TYPE_INTEGER;
  80. val->required = NO;
  81. val->options = "1-3";
  82. val->answer = "1";
  83. val->description = _("Rectification polynomial order (1-3)");
  84. sep = G_define_standard_option(G_OPT_F_SEP);
  85. sep->label = _("Field separator for RMS report");
  86. flag_use3d = G_define_flag();
  87. flag_use3d->key = '3';
  88. flag_use3d->description = _("Perform 3D transformation");
  89. ortho = G_define_flag();
  90. ortho->key = 'o';
  91. ortho->description = _("Perform orthogonal 3D transformation");
  92. print_rms = G_define_flag();
  93. print_rms->key = 'r';
  94. print_rms->label = _("Print RMS errors");
  95. print_rms->description = _("Print RMS errors and exit without rectifying the input map");
  96. no_topo = G_define_standard_flag(G_FLG_V_TOPO);
  97. if (G_parser(argc, argv))
  98. exit(EXIT_FAILURE);
  99. if (grp->answer) {
  100. G_strip(grp->answer);
  101. strcpy(group, grp->answer);
  102. }
  103. else
  104. group[0] = '\0';
  105. points_file = pfile->answer;
  106. if (grp->answer == NULL && points_file == NULL)
  107. G_fatal_error(_("Please select a group or give an input file."));
  108. else if (grp->answer != NULL && points_file != NULL)
  109. G_warning(_("Points in group will be ignored, GCPs in input file are used."));
  110. order = atoi(val->answer);
  111. if (order < 1 || order > MAXORDER)
  112. G_fatal_error(_("Invalid order (%d); please enter 1 to %d"), order,
  113. MAXORDER);
  114. Vect_set_open_level(1);
  115. if (Vect_open_old2(&In, in_opt->answer, "", "") < 0)
  116. G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);
  117. use3d = (Vect_is_3d(&In) &&
  118. (flag_use3d->answer || ortho->answer));
  119. if (!use3d && (flag_use3d->answer || ortho->answer))
  120. G_fatal_error(_("3D transformation requires a 3D vector"));
  121. if (use3d && !points_file)
  122. G_fatal_error(_("A file with 3D control points is needed for 3D transformation"));
  123. orthorot = ortho->answer;
  124. if (print_rms->answer)
  125. rms_sep = G_option_to_separator(sep);
  126. else
  127. rms_sep = NULL;
  128. if (rfile->answer) {
  129. if (strcmp(rfile->answer, "-")) {
  130. fp = fopen(rfile->answer, "w");
  131. if (!fp)
  132. G_fatal_error(_("Unable to open file '%s' for writing"),
  133. rfile->answer);
  134. }
  135. else
  136. fp = stdout;
  137. }
  138. else
  139. fp = stdout;
  140. /* read the control points for the group */
  141. get_control_points(group, points_file, order, use3d, orthorot,
  142. print_rms->answer, rms_sep, fp);
  143. if (print_rms->answer) {
  144. Vect_close(&In);
  145. exit(EXIT_SUCCESS);
  146. }
  147. /* get the target */
  148. get_target(group);
  149. /* Check the GRASS_OVERWRITE environment variable */
  150. if ((overstr = getenv("GRASS_OVERWRITE"))) /* OK ? */
  151. target_overwrite = atoi(overstr);
  152. if (!target_overwrite) {
  153. /* check if output exists in target location/mapset */
  154. select_target_env();
  155. if (G_find_vector2(out_opt->answer, G_mapset())) {
  156. G_warning(_("The vector map <%s> already exists in"), out_opt->answer);
  157. G_warning(_("target LOCATION %s, MAPSET %s:"),
  158. G_location(), G_mapset());
  159. G_fatal_error(_("Rectification cancelled."));
  160. }
  161. select_current_env();
  162. }
  163. else
  164. G_debug(1, "Overwriting OK");
  165. select_target_env();
  166. if (Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In)) < 0)
  167. G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
  168. Vect_copy_head_data(&In, &Out);
  169. Vect_hist_copy(&In, &Out);
  170. Vect_hist_command(&Out);
  171. select_current_env();
  172. Points = Vect_new_line_struct();
  173. OPoints = Vect_new_line_struct();
  174. Cats = Vect_new_cats_struct();
  175. /* count lines */
  176. nlines = 0;
  177. while (1) {
  178. type = Vect_read_next_line(&In, Points, Cats);
  179. if (type == 0)
  180. continue; /* Dead */
  181. if (type == -1)
  182. G_fatal_error(_("Reading input vector map"));
  183. if (type == -2)
  184. break;
  185. nlines++;
  186. }
  187. Vect_rewind(&In);
  188. i = 0;
  189. z = 0.0;
  190. while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
  191. G_percent(i++, nlines, 4);
  192. Vect_reset_line(OPoints);
  193. for (n = 0; n < Vect_get_num_line_points(Points); n++) {
  194. if (use3d) {
  195. if (orthorot)
  196. CRS_georef_or(Points->x[n], Points->y[n], Points->z[n],
  197. &x, &y, &z, OR12);
  198. else
  199. CRS_georef_3d(Points->x[n], Points->y[n], Points->z[n],
  200. &x, &y, &z, E12, N12, Z12, order);
  201. }
  202. else {
  203. I_georef(Points->x[n], Points->y[n],
  204. &x, &y, E12, N12, order);
  205. z = Points->z[n];
  206. }
  207. Vect_append_point(OPoints, x, y, z);
  208. }
  209. select_target_env();
  210. Vect_write_line(&Out, type, OPoints, Cats);
  211. select_current_env();
  212. }
  213. G_percent(1, 1, 1);
  214. select_target_env();
  215. if (!no_topo->answer)
  216. Vect_build(&Out);
  217. /* Copy tables */
  218. G_message(_("Copying attribute table(s)..."));
  219. if (Vect_copy_tables(&In, &Out, 0))
  220. G_warning(_("Failed to copy attribute table to output map"));
  221. Vect_close(&Out);
  222. select_current_env();
  223. Vect_close(&In);
  224. G_done_msg(" ");
  225. exit(EXIT_SUCCESS);
  226. }