crs3d.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /***********************************************************************
  2. crs3d.c
  3. written by: Markus Metz
  4. based on crs.c - Center for Remote Sensing rectification routines
  5. ************************************************************************/
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include <limits.h>
  11. #include <grass/gis.h>
  12. #include <grass/imagery.h>
  13. #include "crs.h"
  14. /* STRUCTURE FOR USE INTERNALLY WITH THESE FUNCTIONS. THESE FUNCTIONS EXPECT
  15. SQUARE MATRICES SO ONLY ONE VARIABLE IS GIVEN (N) FOR THE MATRIX SIZE */
  16. struct MATRIX
  17. {
  18. int n; /* SIZE OF THIS MATRIX (N x N) */
  19. double *v;
  20. };
  21. /* CALCULATE OFFSET INTO ARRAY BASED ON R/C */
  22. #define M(row,col) m->v[(((row)-1)*(m->n))+(col)-1]
  23. #define MSUCCESS 1 /* SUCCESS */
  24. #define MNPTERR 0 /* NOT ENOUGH POINTS */
  25. #define MUNSOLVABLE -1 /* NOT SOLVABLE */
  26. #define MMEMERR -2 /* NOT ENOUGH MEMORY */
  27. #define MPARMERR -3 /* PARAMETER ERROR */
  28. #define MINTERR -4 /* INTERNAL ERROR */
  29. /***********************************************************************
  30. FUNCTION PROTOTYPES FOR STATIC (INTERNAL) FUNCTIONS
  31. ************************************************************************/
  32. static int calccoef(struct Control_Points_3D *, double *, double *, double *, int);
  33. static int calcls(struct Control_Points_3D *, struct MATRIX *,
  34. double *, double *, double *,
  35. double *, double *, double *);
  36. static int exactdet(struct Control_Points_3D *, struct MATRIX *,
  37. double *, double *, double *,
  38. double *, double *, double *);
  39. static int solvemat(struct MATRIX *, double *, double *, double *,
  40. double *, double *, double *);
  41. static double term(int, double, double, double);
  42. /***********************************************************************
  43. TRANSFORM A SINGLE COORDINATE PAIR.
  44. ************************************************************************/
  45. int CRS_georef_3d(double e1, /* EASTING TO BE TRANSFORMED */
  46. double n1, /* NORTHING TO BE TRANSFORMED */
  47. double z1, /* HEIGHT TO BE TRANSFORMED */
  48. double *e, /* EASTING, TRANSFORMED */
  49. double *n, /* NORTHING, TRANSFORMED */
  50. double *z, /* HEIGHT, TRANSFORMED */
  51. double E[], /* EASTING COEFFICIENTS */
  52. double N[], /* NORTHING COEFFICIENTS */
  53. double Z[], /* HEIGHT COEFFICIENTS */
  54. int order /* ORDER OF TRANSFORMATION TO BE PERFORMED, MUST MATCH THE
  55. ORDER USED TO CALCULATE THE COEFFICIENTS */
  56. )
  57. {
  58. double e2, n2, z2, en, ez, nz,
  59. e3, n3, z3, e2n, e2z, en2, ez2, n2z, nz2, enz;
  60. switch (order) {
  61. case 1:
  62. *e = E[0] + E[1] * e1 + E[2] * n1 + E[3] * z1;
  63. *n = N[0] + N[1] * e1 + N[2] * n1 + N[3] * z1;
  64. *z = Z[0] + Z[1] * e1 + Z[2] * n1 + Z[3] * z1;
  65. break;
  66. case 2:
  67. e2 = e1 * e1;
  68. en = e1 * n1;
  69. ez = e1 * z1;
  70. n2 = n1 * n1;
  71. nz = n1 * z1;
  72. z2 = z1 * z1;
  73. *e = E[0] + E[1] * e1 + E[2] * n1 + E[3] * z1 +
  74. E[4] * e2 + E[5] * en + E[6] * ez + E[7] * n2 + E[8] * nz + E[9] * z2;
  75. *n = N[0] + N[1] * e1 + N[2] * n1 + N[3] * z1 +
  76. N[4] * e2 + N[5] * en + N[6] * ez + N[7] * n2 + N[8] * nz + N[9] * z2;
  77. *z = Z[0] + Z[1] * e1 + Z[2] * n1 + Z[3] * z1 +
  78. Z[4] * e2 + Z[5] * en + Z[6] * ez + Z[7] * n2 + Z[8] * nz + Z[9] * z2;
  79. break;
  80. case 3:
  81. e2 = e1 * e1;
  82. en = e1 * n1;
  83. ez = e1 * z1;
  84. n2 = n1 * n1;
  85. nz = n1 * z1;
  86. z2 = z1 * z1;
  87. e3 = e1 * e2;
  88. e2n = e2 * n1;
  89. e2z = e2 * z1;
  90. en2 = e1 * n2;
  91. enz = e1 * n1 * z1;
  92. ez2 = e1 * z2;
  93. n3 = n1 * n2;
  94. n2z = n2 * z1;
  95. nz2 = n1 * z2;
  96. z3 = z1 * z2;
  97. *e = E[0] + E[1] * e1 + E[2] * n1 + E[3] * z1 +
  98. E[4] * e2 + E[5] * en + E[6] * ez + E[7] * n2 + E[8] * nz + E[9] * z2 +
  99. E[10] * e3 + E[11] * e2n + E[12] * e2z + E[13] * en2 + E[14] * enz +
  100. E[15] * ez2 + E[16] * n3 + E[17] * n2z + E[18] * nz2 + E[19] * z3;
  101. *n = N[0] + N[1] * e1 + N[2] * n1 + N[3] * z1 +
  102. N[4] * e2 + N[5] * en + N[6] * ez + N[7] * n2 + N[8] * nz + N[9] * z2 +
  103. N[10] * e3 + N[11] * e2n + N[12] * e2z + N[13] * en2 + N[14] * enz +
  104. N[15] * ez2 + N[16] * n3 + N[17] * n2z + N[18] * nz2 + N[19] * z3;
  105. *z = Z[0] + Z[1] * e1 + Z[2] * n1 + Z[3] * z1 +
  106. Z[4] * e2 + Z[5] * en + Z[6] * ez + Z[7] * n2 + Z[8] * nz + Z[9] * z2 +
  107. Z[10] * e3 + Z[11] * e2n + Z[12] * e2z + Z[13] * en2 + Z[14] * enz +
  108. Z[15] * ez2 + Z[16] * n3 + Z[17] * n2z + Z[18] * nz2 + Z[19] * z3;
  109. break;
  110. default:
  111. return MPARMERR;
  112. }
  113. return MSUCCESS;
  114. }
  115. /***********************************************************************
  116. COMPUTE THE FORWARD AND BACKWARD GEOREFFERENCING COEFFICIENTS
  117. BASED ON A SET OF CONTROL POINTS
  118. ************************************************************************/
  119. int CRS_compute_georef_equations_3d(struct Control_Points_3D *cp,
  120. double E12[], double N12[], double Z12[],
  121. double E21[], double N21[], double Z21[],
  122. int order)
  123. {
  124. double *tempptr;
  125. int status;
  126. if (order < 1 || order > MAXORDER)
  127. return MPARMERR;
  128. /* CALCULATE THE FORWARD TRANSFORMATION COEFFICIENTS */
  129. status = calccoef(cp, E12, N12, Z12, order);
  130. if (status != MSUCCESS)
  131. return status;
  132. /* SWITCH THE 1 AND 2 EASTING, NORTHING, AND HEIGHT ARRAYS */
  133. tempptr = cp->e1;
  134. cp->e1 = cp->e2;
  135. cp->e2 = tempptr;
  136. tempptr = cp->n1;
  137. cp->n1 = cp->n2;
  138. cp->n2 = tempptr;
  139. tempptr = cp->z1;
  140. cp->z1 = cp->z2;
  141. cp->z2 = tempptr;
  142. /* CALCULATE THE BACKWARD TRANSFORMATION COEFFICIENTS */
  143. status = calccoef(cp, E21, N21, Z21, order);
  144. /* SWITCH THE 1 AND 2 EASTING, NORTHING, AND HEIGHT ARRAYS BACK */
  145. tempptr = cp->e1;
  146. cp->e1 = cp->e2;
  147. cp->e2 = tempptr;
  148. tempptr = cp->n1;
  149. cp->n1 = cp->n2;
  150. cp->n2 = tempptr;
  151. tempptr = cp->z1;
  152. cp->z1 = cp->z2;
  153. cp->z2 = tempptr;
  154. return status;
  155. }
  156. /***********************************************************************
  157. COMPUTE THE GEOREFFERENCING COEFFICIENTS
  158. BASED ON A SET OF CONTROL POINTS
  159. ************************************************************************/
  160. static int calccoef(struct Control_Points_3D *cp,
  161. double E[], double N[], double Z[],
  162. int order)
  163. {
  164. struct MATRIX m;
  165. double *a;
  166. double *b;
  167. double *c;
  168. int numactive; /* NUMBER OF ACTIVE CONTROL POINTS */
  169. int status, i;
  170. /* CALCULATE THE NUMBER OF VALID CONTROL POINTS */
  171. for (i = numactive = 0; i < cp->count; i++) {
  172. if (cp->status[i] > 0)
  173. numactive++;
  174. }
  175. /* CALCULATE THE MINIMUM NUMBER OF CONTROL POINTS NEEDED TO DETERMINE
  176. A TRANSFORMATION OF THIS ORDER */
  177. /*
  178. 2D 3D
  179. 1st order: 3 4
  180. 2nd order: 6 10
  181. 3rd order: 10 20
  182. */
  183. m.n = numactive + 1;
  184. if (order == 1)
  185. m.n = 4;
  186. else if (order == 2)
  187. m.n = 10;
  188. else if (order == 3)
  189. m.n = 20;
  190. if (numactive < m.n)
  191. return MNPTERR;
  192. /* INITIALIZE MATRIX */
  193. m.v = G_calloc(m.n * m.n, sizeof(double));
  194. a = G_calloc(m.n, sizeof(double));
  195. b = G_calloc(m.n, sizeof(double));
  196. c = G_calloc(m.n, sizeof(double));
  197. if (numactive == m.n)
  198. status = exactdet(cp, &m, a, b, c, E, N, Z);
  199. else
  200. status = calcls(cp, &m, a, b, c, E, N, Z);
  201. G_free(m.v);
  202. G_free(a);
  203. G_free(b);
  204. G_free(c);
  205. return status;
  206. }
  207. /***********************************************************************
  208. CALCULATE THE TRANSFORMATION COEFFICIENTS WITH EXACTLY THE MINIMUM
  209. NUMBER OF CONTROL POINTS REQUIRED FOR THIS TRANSFORMATION.
  210. ************************************************************************/
  211. static int exactdet(struct Control_Points_3D *cp, struct MATRIX *m,
  212. double a[], double b[], double c[],
  213. double E[], /* EASTING COEFFICIENTS */
  214. double N[], /* NORTHING COEFFICIENTS */
  215. double Z[] /* HEIGHT COEFFICIENTS */
  216. )
  217. {
  218. int pntnow, currow, j;
  219. currow = 1;
  220. for (pntnow = 0; pntnow < cp->count; pntnow++) {
  221. if (cp->status[pntnow] > 0) {
  222. /* POPULATE MATRIX M */
  223. for (j = 1; j <= m->n; j++)
  224. M(currow, j) = term(j, cp->e1[pntnow], cp->n1[pntnow], cp->z1[pntnow]);
  225. /* POPULATE MATRIX A AND B */
  226. a[currow - 1] = cp->e2[pntnow];
  227. b[currow - 1] = cp->n2[pntnow];
  228. c[currow - 1] = cp->z2[pntnow];
  229. currow++;
  230. }
  231. }
  232. if (currow - 1 != m->n)
  233. return MINTERR;
  234. return solvemat(m, a, b, c, E, N, Z);
  235. }
  236. /***********************************************************************
  237. CALCULATE THE TRANSFORMATION COEFFICIENTS WITH MORE THAN THE MINIMUM
  238. NUMBER OF CONTROL POINTS REQUIRED FOR THIS TRANSFORMATION. THIS
  239. ROUTINE USES THE LEAST SQUARES METHOD TO COMPUTE THE COEFFICIENTS.
  240. ************************************************************************/
  241. static int calcls(struct Control_Points_3D *cp, struct MATRIX *m,
  242. double a[], double b[], double c[],
  243. double E[], /* EASTING COEFFICIENTS */
  244. double N[], /* NORTHING COEFFICIENTS */
  245. double Z[] /* HEIGHT COEFFICIENTS */
  246. )
  247. {
  248. int i, j, n, numactive = 0;
  249. /* INITIALIZE THE UPPER HALF OF THE MATRIX AND THE TWO COLUMN VECTORS */
  250. for (i = 1; i <= m->n; i++) {
  251. for (j = i; j <= m->n; j++)
  252. M(i, j) = 0.0;
  253. a[i - 1] = b[i - 1] = c[i - 1] = 0.0;
  254. }
  255. /* SUM THE UPPER HALF OF THE MATRIX AND THE COLUMN VECTORS ACCORDING TO
  256. THE LEAST SQUARES METHOD OF SOLVING OVER DETERMINED SYSTEMS */
  257. for (n = 0; n < cp->count; n++) {
  258. if (cp->status[n] > 0) {
  259. numactive++;
  260. for (i = 1; i <= m->n; i++) {
  261. for (j = i; j <= m->n; j++)
  262. M(i, j) += term(i, cp->e1[n], cp->n1[n], cp->z1[n]) *
  263. term(j, cp->e1[n], cp->n1[n], cp->z1[n]);
  264. a[i - 1] += cp->e2[n] * term(i, cp->e1[n], cp->n1[n], cp->z1[n]);
  265. b[i - 1] += cp->n2[n] * term(i, cp->e1[n], cp->n1[n], cp->z1[n]);
  266. c[i - 1] += cp->z2[n] * term(i, cp->e1[n], cp->n1[n], cp->z1[n]);
  267. }
  268. }
  269. }
  270. if (numactive <= m->n)
  271. return MINTERR;
  272. /* TRANSPOSE VALUES IN UPPER HALF OF M TO OTHER HALF */
  273. for (i = 2; i <= m->n; i++)
  274. for (j = 1; j < i; j++)
  275. M(i, j) = M(j, i);
  276. return solvemat(m, a, b, c, E, N, Z);
  277. }
  278. /***********************************************************************
  279. CALCULATE THE X/Y TERM BASED ON THE TERM NUMBER
  280. ORDER\TERM 1 2 3 4 5 6 7 8 9 10
  281. 1 e0n0z0 e1n0z0 e0n1z0 e0n0z1
  282. 2 e0n0z0 e1n0z0 e0n1z0 e0n0z1 e2n0z0 e1n1z0 e1n0z1 e0n2z0 e0n1z1 e0n0z2
  283. 3 e0n0z0 e1n0z0 e0n1z0 e0n0z1 e2n0z0 e1n1z0 e1n0z1 e0n2z0 e0n1z1 e0n0z2
  284. ORDER\TERM 11 12 13 14 15 16 17 18 19 20
  285. 3 e3n0z0 e2n1z0 e2n0z1 e1n2z0 e1n1z1 e1n0z2 e0n3z0 e0n2z1 e0n1z2 e0n0z3
  286. ************************************************************************/
  287. static double term(int term, double e, double n, double z)
  288. {
  289. switch (term) {
  290. /* 1st order */
  291. case 1:
  292. return 1.0;
  293. case 2:
  294. return e;
  295. case 3:
  296. return n;
  297. case 4:
  298. return z;
  299. /* 2nd order */
  300. case 5:
  301. return e * e;
  302. case 6:
  303. return e * n;
  304. case 7:
  305. return e * z;
  306. case 8:
  307. return n * n;
  308. case 9:
  309. return n * z;
  310. case 10:
  311. return z * z;
  312. /* 3rd order */
  313. case 11:
  314. return e * e * e;
  315. case 12:
  316. return e * e * n;
  317. case 13:
  318. return e * e * z;
  319. case 14:
  320. return e * n * n;
  321. case 15:
  322. return e * n * z;
  323. case 16:
  324. return e * z * z;
  325. case 17:
  326. return n * n * n;
  327. case 18:
  328. return n * n * z;
  329. case 19:
  330. return n * z * z;
  331. case 20:
  332. return z * z * z;
  333. }
  334. return 0.0;
  335. }
  336. /***********************************************************************
  337. SOLVE FOR THE 'E', 'N' AND 'Z' COEFFICIENTS BY USING A
  338. SOMEWHAT MODIFIED GAUSSIAN ELIMINATION METHOD.
  339. | M11 M12 ... M1n | | E0 | | a0 |
  340. | M21 M22 ... M2n | | E1 | = | a1 |
  341. | . . . . | | . | | . |
  342. | Mn1 Mn2 ... Mnn | | En-1 | | an-1 |
  343. ,
  344. | M11 M12 ... M1n | | N0 | | b0 |
  345. | M21 M22 ... M2n | | N1 | = | b1 |
  346. | . . . . | | . | | . |
  347. | Mn1 Mn2 ... Mnn | | Nn-1 | | bn-1 |
  348. and
  349. | M11 M12 ... M1n | | Z0 | | c0 |
  350. | M21 M22 ... M2n | | Z1 | = | c1 |
  351. | . . . . | | . | | . |
  352. | Mn1 Mn2 ... Mnn | | Zn-1 | | cn-1 |
  353. ************************************************************************/
  354. static int solvemat(struct MATRIX *m, double a[], double b[], double c[],
  355. double E[], double N[], double Z[])
  356. {
  357. int i, j, i2, j2, imark;
  358. double factor, temp;
  359. double pivot; /* ACTUAL VALUE OF THE LARGEST PIVOT CANDIDATE */
  360. for (i = 1; i <= m->n; i++) {
  361. j = i;
  362. /* find row with largest magnitude value for pivot value */
  363. pivot = M(i, j);
  364. imark = i;
  365. for (i2 = i + 1; i2 <= m->n; i2++) {
  366. temp = fabs(M(i2, j));
  367. if (temp > fabs(pivot)) {
  368. pivot = M(i2, j);
  369. imark = i2;
  370. }
  371. }
  372. /* if the pivot is very small then the points are nearly co-linear */
  373. /* co-linear points result in an undefined matrix, and nearly */
  374. /* co-linear points results in a solution with rounding error */
  375. if (fabs(pivot) < GRASS_EPSILON)
  376. return MUNSOLVABLE;
  377. /* if row with highest pivot is not the current row, switch them */
  378. if (imark != i) {
  379. for (j2 = 1; j2 <= m->n; j2++) {
  380. temp = M(imark, j2);
  381. M(imark, j2) = M(i, j2);
  382. M(i, j2) = temp;
  383. }
  384. temp = a[imark - 1];
  385. a[imark - 1] = a[i - 1];
  386. a[i - 1] = temp;
  387. temp = b[imark - 1];
  388. b[imark - 1] = b[i - 1];
  389. b[i - 1] = temp;
  390. temp = c[imark - 1];
  391. c[imark - 1] = c[i - 1];
  392. c[i - 1] = temp;
  393. }
  394. /* compute zeros above and below the pivot, and compute
  395. values for the rest of the row as well */
  396. for (i2 = 1; i2 <= m->n; i2++) {
  397. if (i2 != i) {
  398. factor = M(i2, j) / pivot;
  399. for (j2 = j; j2 <= m->n; j2++)
  400. M(i2, j2) -= factor * M(i, j2);
  401. a[i2 - 1] -= factor * a[i - 1];
  402. b[i2 - 1] -= factor * b[i - 1];
  403. c[i2 - 1] -= factor * c[i - 1];
  404. }
  405. }
  406. }
  407. /* SINCE ALL OTHER VALUES IN THE MATRIX ARE ZERO NOW, CALCULATE THE
  408. COEFFICIENTS BY DIVIDING THE COLUMN VECTORS BY THE DIAGONAL VALUES. */
  409. for (i = 1; i <= m->n; i++) {
  410. E[i - 1] = a[i - 1] / M(i, i);
  411. N[i - 1] = b[i - 1] / M(i, i);
  412. Z[i - 1] = c[i - 1] / M(i, i);
  413. }
  414. return MSUCCESS;
  415. }