cp.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <grass/imagery.h>
  8. #include <grass/glocale.h>
  9. #include "global.h"
  10. #include "crs.h"
  11. struct Stats
  12. {
  13. double x, y, z, g;
  14. double sum2, rms;
  15. };
  16. static void update_stats(struct Stats *st, int n,
  17. double dx, double dy, double *dz,
  18. double dg, double d2)
  19. {
  20. st->x += dx;
  21. st->y += dy;
  22. if (dz)
  23. st->z += *dz;
  24. st->g += dg;
  25. st->sum2 += d2;
  26. }
  27. static void diagonal(double *dg, double *d2, double dx, double dy, double *dz)
  28. {
  29. *d2 = dx * dx + dy * dy;
  30. if (dz)
  31. *d2 += *dz * *dz;
  32. *dg = sqrt(*d2);
  33. }
  34. static void compute_rms(struct Control_Points *cp, struct Control_Points_3D *cp3,
  35. int order, int use3d, int orthorot, char *sep, FILE *fp)
  36. {
  37. int n;
  38. int count, npoints;
  39. struct Stats fwd, rev;
  40. fwd.sum2 = fwd.rms = rev.sum2 = rev.rms = 0.0;
  41. fwd.x = fwd.y = fwd.z = fwd.g = 0.0;
  42. rev.x = rev.y = rev.z = rev.g = 0.0;
  43. count = 0;
  44. /* print index, forward difference, backward difference,
  45. * forward rms, backward rms */
  46. if (use3d)
  47. fprintf(fp, "index%sfwd_dx%sfwd_dy%sfwd_dz%sback_dx%sback_dy%sback_dz%sfwd_RMS%sback_RMS",
  48. sep, sep, sep, sep, sep, sep, sep, sep);
  49. else
  50. fprintf(fp, "index%sfwd_dx%sfwd_dy%sback_dx%sback_dy%sfwd_RMS%sback_RMS",
  51. sep, sep, sep, sep, sep, sep);
  52. fprintf(fp, "\n");
  53. if (use3d)
  54. npoints = cp3->count;
  55. else
  56. npoints = cp->count;
  57. for (n = 0; n < npoints; n++) {
  58. double e1, n1, z1, e2, n2, z2;
  59. double fx, fy, fz, fd, fd2;
  60. double rx, ry, rz, rd, rd2;
  61. if (use3d || orthorot) {
  62. if (cp3->status[n] <= 0)
  63. continue;
  64. }
  65. else {
  66. if (cp->status[n] <= 0)
  67. continue;
  68. }
  69. count++;
  70. /* forward: source -> target */
  71. if (use3d) {
  72. if (orthorot)
  73. CRS_georef_or(cp3->e1[n], cp3->n1[n], cp3->z1[n],
  74. &e2, &n2, &z2, OR12);
  75. else
  76. CRS_georef_3d(cp3->e1[n], cp3->n1[n], cp3->z1[n],
  77. &e2, &n2, &z2,
  78. E12, N12, Z12,
  79. order);
  80. fx = fabs(e2 - cp3->e2[n]);
  81. fy = fabs(n2 - cp3->n2[n]);
  82. fz = fabs(z2 - cp3->z2[n]);
  83. diagonal(&fd, &fd2, fx, fy, &fz);
  84. update_stats(&fwd, n, fx, fy, &fz, fd, fd2);
  85. }
  86. else {
  87. I_georef(cp->e1[n], cp->n1[n], &e2, &n2, E12, N12, order);
  88. fx = fabs(e2 - cp->e2[n]);
  89. fy = fabs(n2 - cp->n2[n]);
  90. diagonal(&fd, &fd2, fx, fy, NULL);
  91. update_stats(&fwd, n, fx, fy, NULL, fd, fd2);
  92. }
  93. /* backward: target -> source */
  94. if (use3d) {
  95. if (orthorot)
  96. CRS_georef_or(cp3->e2[n], cp3->n2[n], cp3->z2[n],
  97. &e1, &n1, &z1, OR21);
  98. else
  99. CRS_georef_3d(cp3->e2[n], cp3->n2[n], cp3->z2[n],
  100. &e1, &n1, &z1,
  101. E21, N21, Z21,
  102. order);
  103. rx = fabs(e1 - cp3->e1[n]);
  104. ry = fabs(n1 - cp3->n1[n]);
  105. rz = fabs(z1 - cp3->z1[n]);
  106. diagonal(&rd, &rd2, rx, ry, &rz);
  107. update_stats(&rev, n, rx, ry, &rz, rd, rd2);
  108. }
  109. else {
  110. I_georef(cp->e2[n], cp->n2[n], &e1, &n1, E21, N21, order);
  111. rx = fabs(e1 - cp->e1[n]);
  112. ry = fabs(n1 - cp->n1[n]);
  113. diagonal(&rd, &rd2, rx, ry, NULL);
  114. update_stats(&rev, n, rx, ry, NULL, rd, rd2);
  115. }
  116. /* print index, forward difference, backward difference,
  117. * forward rms, backward rms */
  118. fprintf(fp, "%d", n + 1);
  119. fprintf(fp, "%s%f%s%f", sep, fx, sep, fy);
  120. if (use3d)
  121. fprintf(fp, "%s%f", sep, fz);
  122. fprintf(fp, "%s%f%s%f", sep, rx, sep, ry);
  123. if (use3d)
  124. fprintf(fp, "%s%f", sep, rz);
  125. fprintf(fp, "%s%.4f", sep, fd);
  126. fprintf(fp, "%s%.4f", sep, rd);
  127. fprintf(fp, "\n");
  128. }
  129. if (count > 0) {
  130. fwd.x /= count;
  131. fwd.y /= count;
  132. fwd.g /= count;
  133. rev.x /= count;
  134. rev.y /= count;
  135. rev.g /= count;
  136. if (use3d) {
  137. fwd.z /= count;
  138. rev.z /= count;
  139. }
  140. fwd.rms = sqrt(fwd.sum2 / count);
  141. rev.rms = sqrt(rev.sum2 / count);
  142. }
  143. fprintf(fp, "%d", count);
  144. fprintf(fp, "%s%f%s%f", sep, fwd.x, sep, fwd.y);
  145. if (use3d)
  146. fprintf(fp, "%s%f", sep, fwd.z);
  147. fprintf(fp, "%s%f%s%f", sep, rev.x, sep, rev.y);
  148. if (use3d)
  149. fprintf(fp, "%s%f", sep, rev.z);
  150. fprintf(fp, "%s%.4f", sep, fwd.rms);
  151. fprintf(fp, "%s%.4f", sep, rev.rms);
  152. fprintf(fp, "\n");
  153. }
  154. int new_control_point_3d(struct Control_Points_3D *cp,
  155. double e1, double n1, double z1,
  156. double e2, double n2, double z2,
  157. int status)
  158. {
  159. int i;
  160. unsigned int size;
  161. if (status < 0)
  162. return 1;
  163. i = (cp->count)++;
  164. size = cp->count * sizeof(double);
  165. cp->e1 = (double *)G_realloc(cp->e1, size);
  166. cp->e2 = (double *)G_realloc(cp->e2, size);
  167. cp->n1 = (double *)G_realloc(cp->n1, size);
  168. cp->n2 = (double *)G_realloc(cp->n2, size);
  169. cp->z1 = (double *)G_realloc(cp->z1, size);
  170. cp->z2 = (double *)G_realloc(cp->z2, size);
  171. size = cp->count * sizeof(int);
  172. cp->status = (int *)G_realloc(cp->status, size);
  173. cp->e1[i] = e1;
  174. cp->e2[i] = e2;
  175. cp->n1[i] = n1;
  176. cp->n2[i] = n2;
  177. cp->z1[i] = z1;
  178. cp->z2[i] = z2;
  179. cp->status[i] = status;
  180. return 0;
  181. }
  182. static int read_control_points(FILE * fd, struct Control_Points *cp)
  183. {
  184. char buf[1000];
  185. double e1, e2, n1, n2;
  186. int status;
  187. cp->count = 0;
  188. /* read the control point lines. format is:
  189. image_east image_north target_east target_north status
  190. */
  191. cp->e1 = NULL;
  192. cp->e2 = NULL;
  193. cp->n1 = NULL;
  194. cp->n2 = NULL;
  195. cp->status = NULL;
  196. while (G_getl2(buf, sizeof buf, fd)) {
  197. G_strip(buf);
  198. if (*buf == '#' || *buf == 0)
  199. continue;
  200. if (sscanf(buf, "%lf%lf%lf%lf%d", &e1, &n1, &e2, &n2, &status) == 5)
  201. I_new_control_point(cp, e1, n1, e2, n2, status);
  202. else
  203. return -4;
  204. }
  205. return 1;
  206. }
  207. static int read_control_points_3d(FILE * fd, struct Control_Points_3D *cp)
  208. {
  209. char buf[1000];
  210. double e1, e2, n1, n2, z1, z2;
  211. int status;
  212. cp->count = 0;
  213. /* read the control point lines. format is:
  214. source_east source_north source_height target_east target_north target_height status
  215. */
  216. cp->e1 = NULL;
  217. cp->e2 = NULL;
  218. cp->n1 = NULL;
  219. cp->n2 = NULL;
  220. cp->z1 = NULL;
  221. cp->z2 = NULL;
  222. cp->status = NULL;
  223. while (G_getl2(buf, sizeof buf, fd)) {
  224. G_strip(buf);
  225. if (*buf == '#' || *buf == 0)
  226. continue;
  227. if (sscanf(buf, "%lf%lf%lf%lf%lf%lf%d", &e1, &n1, &z1, &e2, &n2, &z2, &status) == 7)
  228. new_control_point_3d(cp, e1, n1, z1, e2, n2, z2, status);
  229. else
  230. return -4;
  231. }
  232. return 1;
  233. }
  234. int get_control_points(char *group, char *pfile, int order, int use3d,
  235. int orthorot, int rms, char *sep, FILE *fpr)
  236. {
  237. char msg[200];
  238. struct Control_Points cp;
  239. struct Control_Points_3D cp3;
  240. int ret = 0;
  241. int order_pnts[2][3] = {{ 3, 6, 10 }, { 4, 10, 20 }};
  242. cp.count = cp3.count = 0;
  243. cp.e1 = cp.e2 = cp3.e1 = cp3.e2 = NULL;
  244. cp.n1 = cp.n2 = cp3.n1 = cp3.n2 = NULL;
  245. cp3.z1 = cp3.z2 = NULL;
  246. cp.status = cp3.status = NULL;
  247. msg[0] = '\0';
  248. if (use3d) {
  249. /* read 3D GCPs from points file */
  250. FILE *fp;
  251. int fd, stat;
  252. if ((fd = open(pfile, 0)) < 0)
  253. G_fatal_error(_("Can not open file <%s>"), pfile);
  254. fp = fdopen(fd, "r");
  255. stat = read_control_points_3d(fp, &cp3);
  256. fclose(fp);
  257. if (stat < 0) {
  258. G_fatal_error(_("Bad format in control point file <%s>"),
  259. pfile);
  260. return 0;
  261. }
  262. if (orthorot)
  263. ret = CRS_compute_georef_equations_or(&cp3, OR12, OR21);
  264. else
  265. ret = CRS_compute_georef_equations_3d(&cp3, E12, N12, Z12,
  266. E21, N21, Z21, order);
  267. }
  268. else if (pfile) {
  269. /* read 2D GCPs from points file */
  270. FILE *fp;
  271. int fd, stat;
  272. if ((fd = open(pfile, 0)) < 0)
  273. G_fatal_error(_("Can not open file <%s>"), pfile);
  274. fp = fdopen(fd, "r");
  275. stat = read_control_points(fp, &cp);
  276. fclose(fp);
  277. if (stat < 0) {
  278. G_fatal_error(_("Bad format in control point file <%s>"),
  279. pfile);
  280. return 0;
  281. }
  282. ret = I_compute_georef_equations(&cp, E12, N12, E21, N21, order);
  283. }
  284. else {
  285. /* read group control points */
  286. if (!I_get_control_points(group, &cp))
  287. exit(0);
  288. sprintf(msg, _("Control Point file for group <%s@%s> - "),
  289. group, G_mapset());
  290. ret = I_compute_georef_equations(&cp, E12, N12, E21, N21, order);
  291. }
  292. switch (ret) {
  293. case 0:
  294. sprintf(&msg[strlen(msg)],
  295. _("Not enough active control points for current order, %d are required."),
  296. (orthorot ? 3 : order_pnts[use3d != 0][order - 1]));
  297. break;
  298. case -1:
  299. strcat(msg, _("Poorly placed control points."));
  300. strcat(msg, _(" Can not generate the transformation equation."));
  301. break;
  302. case -2:
  303. strcat(msg, _("Not enough memory to solve for transformation equation"));
  304. break;
  305. case -3:
  306. strcat(msg, _("Invalid order"));
  307. break;
  308. default:
  309. break;
  310. }
  311. if (ret != 1)
  312. G_fatal_error("%s", msg);
  313. if (rms) {
  314. compute_rms(&cp, &cp3, order, use3d, orthorot, sep, fpr);
  315. }
  316. return 1;
  317. }