34 #define M(row,col) m->v[(((row)-1)*(m->n))+(col)-1] 38 #define MUNSOLVABLE -1 46 #define MAX(x,y) ((x) > (y) ? (x) : (y)) 49 #define MIN(x,y) ((x) < (y) ? (x) : (y)) 58 static int calccoef(
struct Control_Points *,
double **,
double **);
59 static int calcls(
struct Control_Points *,
struct MATRIX *,
double *,
60 double *,
double *,
double *);
62 static double tps_base_func(
const double x1,
const double y1,
63 const double x2,
const double y2);
64 static int solvemat(
struct MATRIX *,
double *,
double *,
double *,
double *);
83 double dist, *pe, *pn;
95 *e = E[0] + e1 * E[1] + n1 * E[2];
96 *n = N[0] + e1 * N[1] + n1 * N[2];
99 for (i = 0, j = 0; i < cp->
count; i++) {
102 dist = tps_base_func(e1, n1, pe[i], pn[i]);
104 *e += E[j + 3] * dist;
105 *n += N[j + 3] * dist;
121 double **E12tps,
double **N12tps,
122 double **E21tps,
double **N21tps)
127 double xmax, xmin, ymax, ymin;
130 double sumx, sumy, sumx2, sumy2, sumxy;
131 double SSxx, SSyy, SSxy;
135 for (i = numactive = 0; i < cp->
count; i++) {
143 if (numactive > 100000)
146 xmin = xmax = cp->
e1[0];
147 ymin = ymax = cp->
n1[0];
149 sumx = sumy = sumx2 = sumy2 = sumxy = 0.0;
151 for (i = 0; i < cp->
count; i++ ) {
156 xmax =
MAX(xmax, xx);
157 xmin =
MIN(xmin, xx);
158 ymax =
MAX(ymax, yy);
159 ymin =
MIN(ymin, yy);
172 SSxx = sumx2 - sumx * sumx / numactive;
173 SSyy = sumy2 - sumy * sumy / numactive;
174 SSxy = sumxy - sumx * sumy / numactive;
176 if (delx < 0.001 * dely || dely < 0.001 * delx ||
177 fabs(SSxy * SSxy / (SSxx * SSyy)) > 0.99) {
182 xmin = xmax = cp->
e2[0];
183 ymin = ymax = cp->
n2[0];
185 sumx = sumy = sumx2 = sumy2 = sumxy = 0.0;
186 for (i = 0; i < cp->
count; i++ ) {
191 xmax =
MAX(xmax, xx);
192 xmin =
MIN(xmin, xx);
193 ymax =
MAX(ymax, yy);
194 ymin =
MIN(ymin, yy);
207 SSxx = sumx2 - sumx * sumx / numactive;
208 SSyy = sumy2 - sumy * sumy / numactive;
209 SSxy = sumxy - sumx * sumy / numactive;
211 if (delx < 0.001 * dely || dely < 0.001 * delx ||
212 fabs(SSxy * SSxy / (SSxx * SSyy)) > 0.99) {
219 G_message(
_(
"Calculating forward transformation coefficients"));
220 status = calccoef(cp, E12tps, N12tps);
236 G_message(
_(
"Calculating backward transformation coefficients"));
237 status = calccoef(cp, E21tps, N21tps);
268 for (i = numactive = 0; i < cp->
count; i++) {
277 m.v =
G_calloc(m.n * m.n,
sizeof(
double));
279 G_fatal_error(
_(
"%s: out of memory"),
"I_compute_georef_equations_tps()");
282 G_fatal_error(
_(
"%s: out of memory"),
"I_compute_georef_equations_tps()");
285 G_fatal_error(
_(
"%s: out of memory"),
"I_compute_georef_equations_tps()");
290 G_fatal_error(
_(
"%s: out of memory"),
"I_compute_georef_equations_tps()");
293 G_fatal_error(
_(
"%s: out of memory"),
"I_compute_georef_equations_tps()");
295 status = calcls(cp, &m, a, b, *E, *N);
314 double a[],
double b[],
319 int i, j, n, o, numactive = 0;
320 double dist = 0.0, dx, dy, regularization;
324 for (i = 1; i <= m->n; i++) {
325 for (j = i; j <= m->n; j++) {
330 a[i - 1] =
b[i - 1] = 0.0;
336 for (n = 0; n < cp->
count; n++) {
339 a[numactive + 3] = cp->
e2[n];
340 b[numactive + 3] = cp->
n2[n];
343 M(1, numactive + 3) = 1.0;
344 M(2, numactive + 3) = cp->
e1[n];
345 M(3, numactive + 3) = cp->
n1[n];
347 M(numactive + 3, 1) = 1.0;
348 M(numactive + 3, 2) = cp->
e1[n];
349 M(numactive + 3, 3) = cp->
n1[n];
353 if (numactive < m->n - 3)
357 for (n = 0; n < cp->
count; n++) {
362 for (o = 0; o <= n; o++) {
365 M(i + 3, j + 3) = tps_base_func(cp->
e1[n], cp->
n1[n],
366 cp->
e1[o], cp->
n1[o]);
369 M(j + 3, i + 3) =
M(i + 3, j + 3);
371 dx = cp->
e1[n] - cp->
e1[o];
372 dy = cp->
n1[n] - cp->
n1[o];
373 dist += sqrt(dx * dx + dy * dy);
380 dist /= (numactive * numactive);
381 regularization = 0.01 * dist * dist;
385 return solvemat(m, a,
b, E, N);
408 static int solvemat(
struct MATRIX *m,
double a[],
double b[],
double E[],
411 int i, j, i2, j2, imark;
415 for (i = 1; i <= m->n; i++) {
423 for (i2 = i + 1; i2 <= m->n; i2++) {
424 temp = fabs(
M(i2, j));
425 if (temp > fabs(pivot)) {
441 for (j2 = 1; j2 <= m->n; j2++) {
443 M(imark, j2) =
M(i, j2);
448 a[imark - 1] = a[i - 1];
452 b[imark - 1] =
b[i - 1];
459 for (i2 = 1; i2 <= m->n; i2++) {
461 factor =
M(i2, j) / pivot;
462 for (j2 = j; j2 <= m->n; j2++)
463 M(i2, j2) -= factor *
M(i, j2);
464 a[i2 - 1] -= factor * a[i - 1];
465 b[i2 - 1] -= factor *
b[i - 1];
474 for (i = 1; i <= m->n; i++) {
475 E[i - 1] = a[i - 1] /
M(i, i);
476 N[i - 1] =
b[i - 1] /
M(i, i);
482 static double tps_base_func(
const double x1,
const double y1,
483 const double x2,
const double y2)
488 if ((x1 == x2) && (y1 == y2))
491 dist = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
493 return dist * log(dist) * 0.5;
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int I_compute_georef_equations_tps(struct Control_Points *cp, double **E12tps, double **N12tps, double **E21tps, double **N21tps)
void G_free(void *)
Free allocated memory.
void G_message(const char *,...) __attribute__((format(printf
int I_georef_tps(double e1, double n1, double *e, double *n, double *E, double *N, struct Control_Points *cp, int fwd)
void G_percent(long, long, int)
Print percent complete messages.