main.c 7.7 KB

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