georef.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /****************************************************************************
  2. *
  3. * MODULE: imagery library
  4. * AUTHOR(S): Original author(s) name(s) unknown - written by CERL
  5. * PURPOSE: Image processing library
  6. * COPYRIGHT: (C) 1999, 2005 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public
  9. * License (>=v2). Read the file COPYING that comes with GRASS
  10. * for details.
  11. *
  12. *****************************************************************************/
  13. #include <grass/config.h>
  14. #include <grass/imagery.h>
  15. #include <signal.h>
  16. static int floating_exception;
  17. static void catch(int);
  18. static double determinant(double, double,
  19. double, double, double, double, double, double,
  20. double);
  21. /* find coefficients A,B,C for e2 = A + B*e1 + C*n1
  22. * also compute the reverse equations
  23. *
  24. * return 0 if no points
  25. * -1 if not solvable
  26. * 1 if ok
  27. *
  28. * method is least squares.
  29. * the least squares problem reduces to solving the following
  30. * system of equations for A,B,C
  31. *
  32. * s0*A + s1*B + s2*C = x0
  33. * s1*A + s3*B + s4*C = x1
  34. * s2*A + s4*B + s5*C = x2
  35. *
  36. * use Cramer's rule
  37. *
  38. * | x0 s1 s2 | | s0 x0 s2 | | s0 s1 x0 |
  39. * | x1 s3 s4 | | s1 x1 s4 | | s1 s3 x1 |
  40. * | x2 s4 s5 | | s2 x2 s5 | | s2 s4 x2 |
  41. * A = ------------ B = ------------ C = ------------
  42. * | s0 s1 s2 | | s0 s1 s2 | | s0 s1 s2 |
  43. * | s1 s3 s4 | | s1 s3 s4 | | s1 s3 s4 |
  44. * | s2 s4 s5 | | s2 s4 s5 | | s2 s4 s5 |
  45. *
  46. */
  47. int I_compute_georef_equations(struct Control_Points *cp,
  48. double E12[3], double N12[3], double E21[3],
  49. double N21[3])
  50. {
  51. RETSIGTYPE(*sigfpe) (int);
  52. double s0, s1, s2, s3, s4, s5;
  53. double x0, x1, x2;
  54. double det;
  55. int i;
  56. s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
  57. for (i = 0; i < cp->count; i++) {
  58. if (cp->status[i] <= 0)
  59. continue;
  60. s0 += 1.0;
  61. s1 += cp->e1[i];
  62. s2 += cp->n1[i];
  63. s3 += cp->e1[i] * cp->e1[i];
  64. s4 += cp->e1[i] * cp->n1[i];
  65. s5 += cp->n1[i] * cp->n1[i];
  66. }
  67. if (s0 < 0.5)
  68. return 0;
  69. floating_exception = 0;
  70. sigfpe = signal(SIGFPE, catch);
  71. /* eastings */
  72. x0 = x1 = x2 = 0.0;
  73. for (i = 0; i < cp->count; i++) {
  74. if (cp->status[i] <= 0)
  75. continue;
  76. x0 += cp->e2[i];
  77. x1 += cp->e1[i] * cp->e2[i];
  78. x2 += cp->n1[i] * cp->e2[i];
  79. }
  80. det = determinant(s0, s1, s2, s1, s3, s4, s2, s4, s5);
  81. if (det == 0.0) {
  82. signal(SIGFPE, sigfpe);
  83. return -1;
  84. }
  85. E12[0] = determinant(x0, s1, s2, x1, s3, s4, x2, s4, s5) / det;
  86. E12[1] = determinant(s0, x0, s2, s1, x1, s4, s2, x2, s5) / det;
  87. E12[2] = determinant(s0, s1, x0, s1, s3, x1, s2, s4, x2) / det;
  88. /* northings */
  89. x0 = x1 = x2 = 0.0;
  90. for (i = 0; i < cp->count; i++) {
  91. if (cp->status[i] <= 0)
  92. continue;
  93. x0 += cp->n2[i];
  94. x1 += cp->e1[i] * cp->n2[i];
  95. x2 += cp->n1[i] * cp->n2[i];
  96. }
  97. det = determinant(s0, s1, s2, s1, s3, s4, s2, s4, s5);
  98. if (det == 0.0) {
  99. signal(SIGFPE, sigfpe);
  100. return -1;
  101. }
  102. N12[0] = determinant(x0, s1, s2, x1, s3, s4, x2, s4, s5) / det;
  103. N12[1] = determinant(s0, x0, s2, s1, x1, s4, s2, x2, s5) / det;
  104. N12[2] = determinant(s0, s1, x0, s1, s3, x1, s2, s4, x2) / det;
  105. /* the inverse equations */
  106. s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
  107. for (i = 0; i < cp->count; i++) {
  108. if (cp->status[i] <= 0)
  109. continue;
  110. s0 += 1.0;
  111. s1 += cp->e2[i];
  112. s2 += cp->n2[i];
  113. s3 += cp->e2[i] * cp->e2[i];
  114. s4 += cp->e2[i] * cp->n2[i];
  115. s5 += cp->n2[i] * cp->n2[i];
  116. }
  117. /* eastings */
  118. x0 = x1 = x2 = 0.0;
  119. for (i = 0; i < cp->count; i++) {
  120. if (cp->status[i] <= 0)
  121. continue;
  122. x0 += cp->e1[i];
  123. x1 += cp->e2[i] * cp->e1[i];
  124. x2 += cp->n2[i] * cp->e1[i];
  125. }
  126. det = determinant(s0, s1, s2, s1, s3, s4, s2, s4, s5);
  127. if (det == 0.0) {
  128. signal(SIGFPE, sigfpe);
  129. return -1;
  130. }
  131. E21[0] = determinant(x0, s1, s2, x1, s3, s4, x2, s4, s5) / det;
  132. E21[1] = determinant(s0, x0, s2, s1, x1, s4, s2, x2, s5) / det;
  133. E21[2] = determinant(s0, s1, x0, s1, s3, x1, s2, s4, x2) / det;
  134. /* northings */
  135. x0 = x1 = x2 = 0.0;
  136. for (i = 0; i < cp->count; i++) {
  137. if (cp->status[i] <= 0)
  138. continue;
  139. x0 += cp->n1[i];
  140. x1 += cp->e2[i] * cp->n1[i];
  141. x2 += cp->n2[i] * cp->n1[i];
  142. }
  143. det = determinant(s0, s1, s2, s1, s3, s4, s2, s4, s5);
  144. if (det == 0.0) {
  145. signal(SIGFPE, sigfpe);
  146. return -1;
  147. }
  148. N21[0] = determinant(x0, s1, s2, x1, s3, s4, x2, s4, s5) / det;
  149. N21[1] = determinant(s0, x0, s2, s1, x1, s4, s2, x2, s5) / det;
  150. N21[2] = determinant(s0, s1, x0, s1, s3, x1, s2, s4, x2) / det;
  151. signal(SIGFPE, sigfpe);
  152. return floating_exception ? -1 : 1;
  153. }
  154. static double determinant(double a, double b, double c, double d, double e,
  155. double f, double g, double h, double i)
  156. {
  157. /* compute determinant of 3x3 matrix
  158. * | a b c |
  159. * | d e f |
  160. * | g h i |
  161. */
  162. return a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
  163. }
  164. static void catch(int n)
  165. {
  166. floating_exception = 1;
  167. signal(n, catch);
  168. }
  169. int I_georef(double e1, double n1,
  170. double *e2, double *n2, double E[3], double N[3])
  171. {
  172. *e2 = E[0] + E[1] * e1 + E[2] * n1;
  173. *n2 = N[0] + N[1] * e1 + N[2] * n1;
  174. return 0;
  175. }