00001 #include <vcl_cmath.h>
00002 #include <vnl/vnl_math.h>
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define degree_to_rad (vnl_math::pi/180.0) // Degree to rad conv.
00031 #define dcos(x) vcl_cos((x)*vnl_math::pi/180.0)
00032 #define dsin(x) vcl_sin((x)*vnl_math::pi/180.0)
00033 #define EPSILON 1.0e-12
00034
00035
00036 double ipow(double x, int i)
00037 {
00038 double y = 1.0;
00039 if (i<0) { i *= -1; x = y/x; }
00040 while (i) { if (i%2) y*=x; i/=2; x*=x; }
00041 return y;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051 void wgs72_to_wgs84_deltas
00052 (double phi,
00053 double lamda,
00054 double ,
00055 double *delta_phi,
00056 double *delta_lamda,
00057 double *delta_hgt)
00058 {
00059
00060
00061
00062 double delta_f, a, delta_a, delta_r;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 delta_f = .3121057e-7;
00076 a = 6378135;
00077 delta_a = 2.000;
00078 delta_r = 1.400;
00079
00080
00081 if (lamda < 0)
00082 lamda += 360.0;
00083
00084
00085
00086 *delta_phi = (4.5 * dcos(phi))/(a * dsin(1/3600.0)) +
00087 (delta_f * dsin(2.0 * phi)) / (dsin(1/3600.0));
00088
00089 *delta_lamda = .554;
00090
00091 *delta_hgt = 4.5 * dsin(phi) +
00092 a * delta_f * (dsin(phi) * dsin(phi)) - delta_a + delta_r;
00093
00094
00095 *delta_phi /= 3600.0;
00096 *delta_lamda /= 3600.0;
00097 }
00098
00099
00100
00101
00102
00103 void wgs72_to_wgs84
00104 (
00105 double phi,
00106 double lamda,
00107 double height,
00108 double *wgs84_phi,
00109 double *wgs84_lamda,
00110 double *wgs84_hgt)
00111 {
00112 double delta_phi, delta_lamda, delta_hgt;
00113
00114 wgs72_to_wgs84_deltas(phi, lamda, height,
00115 &delta_phi, &delta_lamda, &delta_hgt);
00116
00117 *wgs84_phi = phi + delta_phi;
00118 *wgs84_lamda = lamda + delta_lamda;
00119 *wgs84_hgt = height + delta_hgt;
00120 }
00121
00122
00123
00124
00125
00126 void wgs84_to_wgs72
00127 (
00128 double phi,
00129 double lamda,
00130 double height,
00131 double *wgs72_phi,
00132 double *wgs72_lamda,
00133 double *wgs72_hgt)
00134 {
00135 double delta_phi, delta_lamda, delta_hgt;
00136
00137 wgs72_to_wgs84_deltas(phi, lamda, height,
00138 &delta_phi, &delta_lamda, &delta_hgt);
00139
00140 *wgs72_phi = phi - delta_phi;
00141 *wgs72_lamda = lamda - delta_lamda;
00142 *wgs72_hgt = height - delta_hgt;
00143 }
00144
00145
00146
00147
00148
00149
00150 void nad27m_to_wgs84_deltas
00151 (double phi,
00152 double lamda,
00153 double ,
00154 double *delta_phi,
00155 double *delta_lamda,
00156 double *delta_hgt)
00157 {
00158
00159
00160
00161
00162 double U,V, K;
00163
00164 K = .05235988;
00165
00166
00167 if (lamda < 0)
00168 lamda += 360.0;
00169
00170
00171
00172 U = K * (phi - 20);
00173 V = K * (lamda -290);
00174
00175 *delta_phi = .67775 + 10.02259*U - 18.72391*V + 12.66341*ipow(U,2) - 32.47686*ipow(V,2) - 52.70768*ipow(U,3) - 13.86527*U*ipow(V,2)
00176 - 16.82734*ipow(V,3) - 59.54646*V*ipow(U,3) + 120.64887*ipow(U,5) + 7.23362*ipow(U,2)*ipow(V,3) + 95.89131*ipow(U,5)*V -2.89651*U*ipow(V,5)
00177 - 1.23778*ipow(V,6) + 70.19213*ipow(U,8) + .84596*ipow(U,2)*ipow(V,6) + .14848*ipow(V,8) - 3.83786*ipow(U,3)*ipow(V,6) + .10405*U*ipow(V,9)
00178 + 30.09795*ipow(U,8)*ipow(V,3) + 12.93585*ipow(U,6)*ipow(V,6) - .58747*ipow(U,3)*ipow(V,9) + .7485*ipow(U,4)*ipow(V,9) +
00179 6.32462*ipow(U,8)*ipow(V,7) - .12736*ipow(U,6)*ipow(V,9) - .59993*ipow(U,9)*ipow(V,9);
00180
00181 *delta_lamda = -.33643 - 3.11777*V -5.16881*ipow(U,2) - 3.17318*ipow(V,2) - 34.59331*ipow(U,3) + .97215*U*ipow(V,2) - .5818*ipow(V,3) +
00182 223.78114*ipow(U,5) + 358.07266*ipow(U,6) + 270.68064*ipow(U,7) - 87.99549*ipow(U,6)*V - .09789*U*ipow(V,6) + 636.41982*ipow(U,7)*V -
00183 729.91514*ipow(U,6)*ipow(V,2) - .60122*ipow(U,3)*ipow(V,5) - 375.38863*ipow(U,6)*ipow(V,3) - 6.97538*ipow(U,4)*ipow(V,5) -
00184 .00138*ipow(V,9) - 363.45977*ipow(U,9)*V + 50.19955*ipow(U,8)*ipow(V,2) - 12.01575*ipow(U,5)*ipow(V,6) - .4314*ipow(U,6)*ipow(V,9) +
00185 .43907*ipow(U,9)*ipow(V,9);
00186
00187 *delta_hgt = -20.013 + 12.815*U - 8.084*V +74.122*ipow(U,2)*V +39.523*ipow(U,2)*ipow(V,2) - 23.158*ipow(U,4)*V + 194.444*ipow(U,6) +
00188 36.797*ipow(U,5)*V + .181*U*ipow(V,5) - 292.155*ipow(U,8) + 3.749*ipow(U,5)*ipow(V,5) +2.537*ipow(U,8)*ipow(V,6);
00189
00190
00191 *delta_phi /= 3600.0;
00192 *delta_lamda /= 3600.0;
00193 }
00194
00195
00196
00197
00198
00199
00200 void nad27m_to_wgs84
00201 (double phi,
00202 double lamda,
00203 double height,
00204 double *wgs84_phi,
00205 double *wgs84_lamda,
00206 double *wgs84_hgt)
00207 {
00208 double delta_phi, delta_lamda, delta_hgt;
00209
00210 nad27m_to_wgs84_deltas(phi, lamda, height,
00211 &delta_phi, &delta_lamda, &delta_hgt);
00212
00213 *wgs84_phi = phi + delta_phi;
00214 *wgs84_lamda = lamda + delta_lamda;
00215 *wgs84_hgt = height + delta_hgt;
00216 }
00217
00218
00219
00220
00221
00222
00223 void wgs84_to_nad27m
00224 (double phi,
00225 double lamda,
00226 double height,
00227 double *nad27m_phi,
00228 double *nad27m_lamda,
00229 double *nad27m_hgt)
00230 {
00231 double delta_phi, delta_lamda, delta_hgt;
00232
00233 nad27m_to_wgs84_deltas(phi, lamda, height,
00234 &delta_phi, &delta_lamda, &delta_hgt);
00235
00236 *nad27m_phi = phi - delta_phi;
00237 *nad27m_lamda = lamda - delta_lamda;
00238 *nad27m_hgt = height - delta_hgt;
00239 }
00240
00241
00242
00243
00244
00245
00246 void nad27n_to_wgs84_deltas
00247 (double phi,
00248 double lamda,
00249 double ,
00250 double *delta_phi,
00251 double *delta_lamda,
00252 double *delta_hgt)
00253 {
00254
00255
00256
00257 double U,V, K;
00258
00259 K = .05235988;
00260
00261
00262 if (lamda < 0)
00263 lamda += 360.0;
00264
00265 U = K * (phi - 37.0);
00266 V = K * (lamda -265.0);
00267
00268
00269
00270 *delta_phi = .16984 - .76173*U + .09585*V +1.09919*ipow(U,2) - 4.57801*ipow(U,3) - 1.13239*ipow(U,2)*V + .49831*ipow(V,3)
00271 - .98399*ipow(U,3)*V + .12415*U*ipow(V,3) + .1145*ipow(V,4) +27.05396*ipow(U,5) + 2.03449*ipow(U,4)*V +.73357*ipow(U,2)*ipow(V,3)
00272 - .37548*ipow(V,5) - .14197*ipow(V,6) -59.96555*ipow(U,7) + .07439*ipow(V,7) -4.76082*ipow(U,8) + .03385*ipow(V,8) +
00273 49.0432*ipow(U,9) - 1.30575*ipow(U,6)*ipow(V,3) - .07653*ipow(U,3)*ipow(V,9) + .08646*ipow(U,4)*ipow(V,9);
00274
00275 *delta_lamda = -.88437 + 2.05061*V + .26361*ipow(U,2) - .76804*U*V + .13374*ipow(V,2) - 1.31974*ipow(U,3) - .52162*ipow(U,2)*V -
00276 1.05853*U*ipow(V,2) -.49211*ipow(U,2)*ipow(V,2) + 2.17204*U*ipow(V,3) -.06004*ipow(V,4) +.30139*ipow(U,4)*V + 1.88585*U*ipow(V,4)
00277 - .81162*U*ipow(V,5) -.05183*ipow(V,6) -.96723*U*ipow(V,6) -.12948*ipow(U,3)*ipow(V,5) + 3.41827*ipow(U,9) -.44507*ipow(U,8)*V
00278 +.18882*U*ipow(V,8) -.01444*ipow(V,9) +.04794*U*ipow(V,9) -.59013*ipow(U,9)*ipow(V,3);
00279
00280 *delta_hgt = -36.526 +3.9*U -4.723*V -21.553*ipow(U,2) +7.294*U*V +8.886*ipow(V,2) -8.44*ipow(U,2)*V -2.93*U*ipow(V,2) +
00281 56.937*ipow(U,4) -58.756*ipow(U,3)*V -4.061*ipow(V,4) +4.447*ipow(U,4)*V +4.903*ipow(U,2)*ipow(V,3) -55.873*ipow(U,6)
00282 +212.005*ipow(U,5)*V + 3.081*ipow(V,6) -254.511*ipow(U,7)*V -.756*ipow(V,8) +30.654*ipow(U,8)*V -.122*U*ipow(V,9);
00283
00284
00285 *delta_phi /= 3600.0;
00286 *delta_lamda /= 3600.0;
00287 }
00288
00289
00290
00291
00292
00293
00294 void nad27n_to_wgs84
00295 (double phi,
00296 double lamda,
00297 double height,
00298 double *wgs84_phi,
00299 double *wgs84_lamda,
00300 double *wgs84_hgt)
00301 {
00302 double delta_phi, delta_lamda, delta_hgt;
00303
00304 nad27n_to_wgs84_deltas(phi, lamda, height,
00305 &delta_phi, &delta_lamda, &delta_hgt);
00306
00307 *wgs84_phi = phi + delta_phi;
00308 *wgs84_lamda = lamda + delta_lamda;
00309 *wgs84_hgt = height + delta_hgt;
00310 }
00311
00312
00313
00314
00315
00316 void wgs84_to_nad27n
00317 (double phi,
00318 double lamda,
00319 double height,
00320 double *nad27n_phi,
00321 double *nad27n_lamda,
00322 double *nad27n_hgt)
00323 {
00324 double delta_phi, delta_lamda, delta_hgt;
00325
00326 nad27n_to_wgs84_deltas(phi, lamda, height,
00327 &delta_phi, &delta_lamda, &delta_hgt);
00328
00329 *nad27n_phi = phi - delta_phi;
00330 *nad27n_lamda = lamda - delta_lamda;
00331 *nad27n_hgt = height - delta_hgt;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 void nad27n_to_wgs84_alternate
00352 (double nad27_lat, double nad27_lon, double nad27_el,
00353 double *wgs84_lat, double *wgs84_lon, double *wgs84_el)
00354 {
00355 double u,v,k;
00356
00357 double a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14;
00358 double a15,a16,a17,a18,a19,a20,a21,a22,a23;
00359
00360 double b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14;
00361 double b15,b16,b17,b18,b19,b20,b21,b22,b23;
00362
00363 double c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14;
00364 double c15,c16,c17,c18,c19,c20;
00365
00366 double delta_lat;
00367 double delta_lon;
00368 double delta_H;
00369 #ifdef DEBUG_DATUM
00370 double N_height;
00371 #endif
00372
00373 double delta_lat_p;
00374 double delta_lon_p;
00375
00376 #ifdef DEBUG_DATUM
00377 double prin_lat_rad;
00378 double ft_lat;
00379 double ft_lon;
00380 double c_error;
00381 #endif
00382
00383 #if 0
00384 int lon_int;
00385 double lon_int_fl;
00386 double lon_frac;
00387 #endif
00388
00389 #ifdef DEBUG_DATUM
00390 double new_lat;
00391 double new_lon;
00392 #endif
00393
00394 double prin_lat;
00395 double prin_lon;
00396
00397 #ifdef DEBUG_DATUM
00398
00399
00400 vcl_cout << "\n NAD27 to WGS84 Conversion routine\n\n"
00401 << " Enter latitude and longitude : ";
00402 vcl_cin >> nad27_lat >> nad27_lon;
00403
00404 #endif
00405
00406 prin_lat = (double) nad27_lat;
00407 prin_lon = (double) nad27_lon;
00408
00409 #ifdef DEBUG_DATUM
00410 prin_lat_rad = prin_lat * degree_to_rad;
00411 #endif
00412
00413
00414
00415
00416
00417 if (prin_lon < 0)
00418 prin_lon = 360.0 + prin_lon;
00419
00420
00421 k = .05235988;
00422 u = k*(prin_lat - 37);
00423 v = k*(prin_lon - 265);
00424
00425
00426
00427 a1 = 0.16984;
00428 a2 = -0.76173;
00429 a3 = 0.09585;
00430 a4 = 1.09919;
00431 a5 = -4.57801;
00432 a6 = -1.13239;
00433 a7 = 0.49831;
00434 a8 = -.98399;
00435 a9 = 0.12415;
00436 a10 = 0.11450;
00437 a11 = 27.05396;
00438 a12 = 2.03449;
00439 a13 = 0.73357;
00440 a14 = -0.37548;
00441 a15 = -0.14197;
00442 a16 = -59.96555;
00443 a17 = 0.07439;
00444 a18 = -4.76082;
00445 a19 = 0.03385;
00446 a20 = 49.04320;
00447 a21 = -1.30575;
00448 a22 = -0.07653;
00449 a23 = 0.08646;
00450
00451 delta_lat = a1 + a2*u + a3*v + a4*u*u + a5*u*u*u + a6*u*u*v
00452 + a7*v*v*v + a8*u*u*u*v + a9*u*v*v*v + a10*v*v*v*v
00453 + a11*u*u*u*u*u + a12*u*u*u*u*v + a13*u*u*v*v*v
00454 + a14*v*v*v*v*v + a15*v*v*v*v*v*v + a16*u*u*u*u*u*u*u
00455 + a17*v*v*v*v*v*v*v + a18*u*u*u*u*u*u*u*u
00456 + a19*v*v*v*v*v*v*v*v + a20*u*u*u*u*u*u*u*u*u
00457 + a21*u*u*u*u*u*u*v*v*v + a22*u*u*u*v*v*v*v*v*v*v*v*v
00458 + a23*u*u*u*u*v*v*v*v*v*v*v*v*v;
00459
00460
00461
00462 b1 = -0.88437;
00463 b2 = 2.05061;
00464 b3 = 0.26361;
00465 b4 = -0.76804;
00466 b5 = 0.13374;
00467 b6 = -1.31974;
00468 b7 = -0.52162;
00469 b8 = -1.05853;
00470 b9 = -0.49211;
00471 b10 = 2.17204;
00472 b11 = -0.06004;
00473 b12 = 0.30139;
00474 b13 = 1.88585;
00475 b14 = -0.81162;
00476 b15 = -0.05183;
00477 b16 = -0.96723;
00478 b17 = -.12948;
00479 b18 = 3.41827;
00480 b19 = -0.44507;
00481 b20 = 0.18882;
00482 b21 = -0.01444;
00483 b22 = 0.04794;
00484 b23 = -0.59013;
00485
00486 delta_lon = b1 + b2*v + b3*u*u + b4*u*v + b5*v*v + b6*u*u*u
00487 + b7*u*u*v + b8*u*v*v + b9*u*u*v*v + b10*u*v*v*v
00488 + b11*v*v*v*v + b12*u*u*u*u*v + b13*u*v*v*v*v
00489 + b14*u*v*v*v*v*v + b15*v*v*v*v*v*v
00490 + b16*u*v*v*v*v*v*v + b17*u*u*u*v*v*v*v*v
00491 + b18*u*u*u*u*u*u*u*u*u + b19*u*u*u*u*u*u*u*u*v
00492 + b20*u*v*v*v*v*v*v*v*v + b21*v*v*v*v*v*v*v*v*v
00493 + b22*u*v*v*v*v*v*v*v*v*v + b23*u*u*u*u*u*u*u*u*u*v*v*v;
00494
00495
00496 c1 = -36.526;
00497 c2 = 3.900;
00498 c3 = -4.723;
00499 c4 = -21.553;
00500 c5 = 7.294;
00501 c6 = 8.886;
00502 c7 = -8.440;
00503 c8 = -2.930;
00504 c9 = 56.937;
00505 c10 = -58.756;
00506 c11 = -4.061;
00507 c12 = 4.447;
00508 c13 = 4.903;
00509 c14 = -55.873;
00510 c15 = 212.005;
00511 c16 = 3.081;
00512 c17 = -254.511;
00513 c18 = -0.756;
00514 c19 = 30.654;
00515 c20 = -0.122;
00516
00517 delta_H = c1 + c2*u + c3*v + c4*u*u + c5*u*v + c6*v*v + c7*u*u*v
00518 + c8*u*v*v + c9*u*u*u*u + c10*u*u*u*v + c11*v*v*v*v
00519 + c12*u*u*u*u*v + c13*u*u*v*v*v + c14*u*u*u*u*u*u
00520 + c15*u*u*u*u*u*v + c16*v*v*v*v*v*v + c17*u*u*u*u*u*u*u*v
00521 + c18*v*v*v*v*v*v*v*v + c19*u*u*u*u*u*u*u*u*v
00522 + c20*v*v*v*v*v*v*v*v*v;
00523
00524
00525 #ifdef DEBUG_DATUM
00526 double d1 = 5.068;
00527 double d2 = -11.570;
00528 double d3 = -8.574;
00529 double d4 = 27.839;
00530 double d5 = -51.911;
00531 double d6 = 29.496;
00532 double d7 = 28.343;
00533 double d8 = 24.481;
00534 double d9 = 11.424;
00535 double d10 = 132.550;
00536 double d11 = -110.232;
00537 double d12 = 41.018;
00538 double d13 = -64.953;
00539 double d14 = -128.293;
00540 double d15 = 51.241;
00541 double d16 = -4.326;
00542 double d17 = 104.097;
00543 double d18 = -128.031;
00544 double d19 = 110.694;
00545 double d20 = 36.330;
00546 double d21 = 243.149;
00547 double d22 = -15.790;
00548 double d23 = -38.043;
00549 double d24 = -40.277;
00550 double d25 = 2.746;
00551 double d26 = -7.321;
00552 double d27 = -394.404;
00553 double d28 = -927.540;
00554 double d29 = 63.390;
00555 double d30 = 10.626;
00556 double d31 = -0.520;
00557 double d32 = -117.207;
00558 double d33 = 16.352;
00559
00560 N_height = d1 + d2*u + d3*v + d4*u*u + d5*u*v + d6*v*v + d7*u*u*u
00561 + d8*u*v*v + d9*v*v*v + d10*u*u*u*v + d11*u*u*v*v
00562 + d12*u*v*v*v + d13*v*v*v*v + d14*u*u*u*v*v + d15*u*v*v*v*v
00563 + d16*v*v*v*v*v + d17*u*u*u*u*v*v + d18*u*u*u*v*v*v
00564 + d19*u*u*v*v*v*v + d20*v*v*v*v*v*v + d21*u*u*u*u*u*u*v
00565 + d22*u*u*v*v*v*v*v + d23*u*v*v*v*v*v*v + d24*u*u*v*v*v*v*v*v
00566 + d25*u*v*v*v*v*v*v*v + d26*v*v*v*v*v*v*v*v
00567 + d27*u*u*u*u*u*u*u*u*u + d28*u*u*u*u*u*u*u*u*v
00568 + d29*u*u*u*u*v*v*v*v*v + d30*u*v*v*v*v*v*v*v*v
00569 + d31*u*v*v*v*v*v*v*v*v*v + d32*u*u*u*u*u*u*u*u*v*v*v*v
00570 + d33*u*u*u*u*u*v*v*v*v*v*v*v*v;
00571 #endif
00572
00573 delta_lat_p = (double)delta_lat;
00574 delta_lon_p = (double)delta_lon;
00575
00576 #ifdef DEBUG_DATUM
00577 ft_lat = 101.0 * delta_lat_p;
00578 ft_lon = 101.0 * vcl_cos(prin_lat_rad) * delta_lon_p;
00579
00580 c_error = (double)vcl_sqrt(ft_lat*ft_lat + ft_lon*ft_lon);
00581 #endif
00582
00583 *wgs84_lat = nad27_lat + (delta_lat_p/3600.0);
00584 *wgs84_lon = nad27_lon + (delta_lon_p/3600.0);
00585 *wgs84_el = nad27_el + delta_H;
00586
00587 #ifdef DEBUG_DATUM
00588 new_lat = *wgs84_lat;
00589 new_lon = *wgs84_lon;
00590 vcl_cout << "\n d_lat = " << delta_lat
00591 << "\n d_lon = " << delta_lon
00592 << "\n d_H = " << delta_H
00593 << "\n N = " << N_height
00594 << "\n circular error = " << c_error
00595 << "\n New Lat = " << new_lat << ", New Lon =\n" << new_lon
00596 << '\n';
00597 #endif
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607 void wgs84_to_nad27n_alternate
00608 (double wgs84_lat, double wgs84_lon, double wgs84_el,
00609 double *nad27n_lat, double *nad27n_lon, double *nad27n_el)
00610 {
00611 double u,v,k;
00612
00613 double a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14;
00614 double a15,a16,a17,a18,a19,a20,a21,a22,a23;
00615
00616 double b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14;
00617 double b15,b16,b17,b18,b19,b20,b21,b22,b23;
00618
00619 double c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14;
00620 double c15,c16,c17,c18,c19,c20;
00621
00622 double delta_lat;
00623 double delta_lon;
00624 double delta_H;
00625 #ifdef DEBUG_DATUM
00626 double N_height;
00627 #endif
00628
00629 double delta_lat_p;
00630 double delta_lon_p;
00631
00632 #ifdef DEBUG_DATUM
00633 double prin_lat_rad;
00634 double ft_lat;
00635 double ft_lon;
00636 double c_error;
00637 #endif
00638
00639 #if 0
00640 int lon_int;
00641 double lon_int_fl;
00642 double lon_frac;
00643 #endif
00644
00645 #ifdef DEBUG_DATUM
00646 double new_lat;
00647 double new_lon;
00648 #endif
00649
00650 double prin_lat;
00651 double prin_lon;
00652
00653 #ifdef DEBUG_DATUM
00654
00655
00656 vcl_cout << "\n wgs84 to NAD27N Conversion routine\n\n";
00657 " Enter latitude, longitude ";
00658 vcl_cin >> wgs84_lat >> wgs84_lon;
00659
00660 #endif
00661
00662 prin_lat = (double) wgs84_lat;
00663 prin_lon = (double) wgs84_lon;
00664
00665 #ifdef DEBUG_DATUM
00666 prin_lat_rad = prin_lat * degree_to_rad;
00667 #endif
00668
00669
00670
00671
00672
00673 if (prin_lon < 0)
00674 prin_lon = 360.0 + prin_lon;
00675
00676
00677 k = .05235988;
00678 u = k*(prin_lat - 37);
00679 v = k*(prin_lon - 265);
00680
00681
00682
00683 a1 = 0.16984;
00684 a2 = -0.76173;
00685 a3 = 0.09585;
00686 a4 = 1.09919;
00687 a5 = -4.57801;
00688 a6 = -1.13239;
00689 a7 = 0.49831;
00690 a8 = -.98399;
00691 a9 = 0.12415;
00692 a10 = 0.11450;
00693 a11 = 27.05396;
00694 a12 = 2.03449;
00695 a13 = 0.73357;
00696 a14 = -0.37548;
00697 a15 = -0.14197;
00698 a16 = -59.96555;
00699 a17 = 0.07439;
00700 a18 = -4.76082;
00701 a19 = 0.03385;
00702 a20 = 49.04320;
00703 a21 = -1.30575;
00704 a22 = -0.07653;
00705 a23 = 0.08646;
00706
00707 delta_lat = a1 + a2*u + a3*v + a4*u*u + a5*u*u*u + a6*u*u*v
00708 + a7*v*v*v + a8*u*u*u*v + a9*u*v*v*v + a10*v*v*v*v
00709 + a11*u*u*u*u*u + a12*u*u*u*u*v + a13*u*u*v*v*v
00710 + a14*v*v*v*v*v + a15*v*v*v*v*v*v + a16*u*u*u*u*u*u*u
00711 + a17*v*v*v*v*v*v*v + a18*u*u*u*u*u*u*u*u
00712 + a19*v*v*v*v*v*v*v*v + a20*u*u*u*u*u*u*u*u*u
00713 + a21*u*u*u*u*u*u*v*v*v + a22*u*u*u*v*v*v*v*v*v*v*v*v
00714 + a23*u*u*u*u*v*v*v*v*v*v*v*v*v;
00715
00716
00717
00718 b1 = -0.88437;
00719 b2 = 2.05061;
00720 b3 = 0.26361;
00721 b4 = -0.76804;
00722 b5 = 0.13374;
00723 b6 = -1.31974;
00724 b7 = -0.52162;
00725 b8 = -1.05853;
00726 b9 = -0.49211;
00727 b10 = 2.17204;
00728 b11 = -0.06004;
00729 b12 = 0.30139;
00730 b13 = 1.88585;
00731 b14 = -0.81162;
00732 b15 = -0.05183;
00733 b16 = -0.96723;
00734 b17 = -.12948;
00735 b18 = 3.41827;
00736 b19 = -0.44507;
00737 b20 = 0.18882;
00738 b21 = -0.01444;
00739 b22 = 0.04794;
00740 b23 = -0.59013;
00741
00742 delta_lon = b1 + b2*v + b3*u*u + b4*u*v + b5*v*v + b6*u*u*u
00743 + b7*u*u*v + b8*u*v*v + b9*u*u*v*v + b10*u*v*v*v
00744 + b11*v*v*v*v + b12*u*u*u*u*v + b13*u*v*v*v*v
00745 + b14*u*v*v*v*v*v + b15*v*v*v*v*v*v
00746 + b16*u*v*v*v*v*v*v + b17*u*u*u*v*v*v*v*v
00747 + b18*u*u*u*u*u*u*u*u*u + b19*u*u*u*u*u*u*u*u*v
00748 + b20*u*v*v*v*v*v*v*v*v + b21*v*v*v*v*v*v*v*v*v
00749 + b22*u*v*v*v*v*v*v*v*v*v + b23*u*u*u*u*u*u*u*u*u*v*v*v;
00750
00751
00752 c1 = -36.526;
00753 c2 = 3.900;
00754 c3 = -4.723;
00755 c4 = -21.553;
00756 c5 = 7.294;
00757 c6 = 8.886;
00758 c7 = -8.440;
00759 c8 = -2.930;
00760 c9 = 56.937;
00761 c10 = -58.756;
00762 c11 = -4.061;
00763 c12 = 4.447;
00764 c13 = 4.903;
00765 c14 = -55.873;
00766 c15 = 212.005;
00767 c16 = 3.081;
00768 c17 = -254.511;
00769 c18 = -0.756;
00770 c19 = 30.654;
00771 c20 = -0.122;
00772
00773 delta_H = c1 + c2*u + c3*v + c4*u*u + c5*u*v + c6*v*v + c7*u*u*v
00774 + c8*u*v*v + c9*u*u*u*u + c10*u*u*u*v + c11*v*v*v*v
00775 + c12*u*u*u*u*v + c13*u*u*v*v*v + c14*u*u*u*u*u*u
00776 + c15*u*u*u*u*u*v + c16*v*v*v*v*v*v + c17*u*u*u*u*u*u*u*v
00777 + c18*v*v*v*v*v*v*v*v + c19*u*u*u*u*u*u*u*u*v
00778 + c20*v*v*v*v*v*v*v*v*v;
00779
00780 #ifdef DEBUG_DATUM
00781 d1 = 5.068;
00782 d2 = -11.570;
00783 d3 = -8.574;
00784 d4 = 27.839;
00785 d5 = -51.911;
00786 d6 = 29.496;
00787 d7 = 28.343;
00788 d8 = 24.481;
00789 d9 = 11.424;
00790 d10 = 132.550;
00791 d11 = -110.232;
00792 d12 = 41.018;
00793 d13 = -64.953;
00794 d14 = -128.293;
00795 d15 = 51.241;
00796 d16 = -4.326;
00797 d17 = 104.097;
00798 d18 = -128.031;
00799 d19 = 110.694;
00800 d20 = 36.330;
00801 d21 = 243.149;
00802 d22 = -15.790;
00803 d23 = -38.043;
00804 d24 = -40.277;
00805 d25 = 2.746;
00806 d26 = -7.321;
00807 d27 = -394.404;
00808 d28 = -927.540;
00809 d29 = 63.390;
00810 d30 = 10.626;
00811 d31 = -0.520;
00812 d32 = -117.207;
00813 d33 = 16.352;
00814
00815 N_height = d1 + d2*u + d3*v + d4*u*u + d5*u*v + d6*v*v + d7*u*u*u
00816 + d8*u*v*v + d9*v*v*v + d10*u*u*u*v + d11*u*u*v*v
00817 + d12*u*v*v*v + d13*v*v*v*v + d14*u*u*u*v*v + d15*u*v*v*v*v
00818 + d16*v*v*v*v*v + d17*u*u*u*u*v*v + d18*u*u*u*v*v*v
00819 + d19*u*u*v*v*v*v + d20*v*v*v*v*v*v + d21*u*u*u*u*u*u*v
00820 + d22*u*u*v*v*v*v*v + d23*u*v*v*v*v*v*v + d24*u*u*v*v*v*v*v*v
00821 + d25*u*v*v*v*v*v*v*v + d26*v*v*v*v*v*v*v*v
00822 + d27*u*u*u*u*u*u*u*u*u + d28*u*u*u*u*u*u*u*u*v
00823 + d29*u*u*u*u*v*v*v*v*v + d30*u*v*v*v*v*v*v*v*v
00824 + d31*u*v*v*v*v*v*v*v*v*v + d32*u*u*u*u*u*u*u*u*v*v*v*v
00825 + d33*u*u*u*u*u*v*v*v*v*v*v*v*v;
00826 #endif
00827
00828 delta_lat_p = (double)delta_lat;
00829 delta_lon_p = (double)delta_lon;
00830
00831 #ifdef DEBUG_DATUM
00832 ft_lat = 101.0 * delta_lat_p;
00833 ft_lon = 101.0 * vcl_cos(prin_lat_rad) * delta_lon_p;
00834
00835 c_error = (double)vcl_sqrt(ft_lat*ft_lat + ft_lon*ft_lon);
00836 #endif
00837
00838
00839 *nad27n_lat = wgs84_lat - (delta_lat_p/3600.0);
00840 *nad27n_lon = wgs84_lon - (delta_lon_p/3600.0);
00841 *nad27n_el = wgs84_el - delta_H;
00842
00843 #ifdef DEBUG_DATUM
00844 new_lat = *nad27n_lat;
00845 new_lon = *nad27n_lon;
00846 vcl_cout << "\n d_lat = " << delta_lat
00847 << "\n d_lon = " << delta_lon
00848 << "\n d_H = " << delta_H
00849 << "\n N = " << N_height
00850 << "\n circular error = " << c_error
00851 << "\n New Lat = " << new_lat << ", New Lon =\n" << new_lon
00852 << '\n';
00853 #endif
00854 }
00855
00856
00857
00858
00859
00860 double geo_detic2centric
00861 (double geodetic_lat,
00862 double A,
00863 double B)
00864 {
00865 return(vcl_atan((B/A)*(B/A) * vcl_tan(geodetic_lat)));
00866 }
00867
00868
00869
00870
00871 double geo_centric2detic
00872 (double geocentric_lat,
00873 double A,
00874 double B)
00875 {
00876 return(vcl_atan((A/B)*(A/B) * vcl_tan(geocentric_lat)));
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 void GRS_to_latlong
00899 (double x, double y, double z,
00900 double *geodetic_lat,
00901 double *lon,
00902 double *el,
00903 double A,
00904 double B)
00905 {
00906 double new_lat;
00907 double N;
00908 double xy_dist;
00909 double ee;
00910
00911 xy_dist = vcl_sqrt(x*x + y*y);
00912 ee = 1 - (B/A)*(B/A);
00913
00914
00915
00916
00917
00918 *lon = vcl_acos(x/xy_dist);
00919 if (y < 0)
00920 *lon = - *lon;
00921
00922
00923 new_lat = vcl_atan2(z, xy_dist);
00924
00925 do
00926 {
00927 *geodetic_lat = new_lat;
00928
00929
00930
00931
00932 N = A / vcl_sqrt(1 - ee * vcl_sin(*geodetic_lat) * vcl_sin(*geodetic_lat));
00933
00934
00935 new_lat = vcl_atan2( (z + N * ee * vcl_sin(*geodetic_lat)), xy_dist );
00936 }
00937 while (vcl_fabs(new_lat - *geodetic_lat) > EPSILON);
00938
00939 *geodetic_lat = new_lat;
00940 *el = xy_dist/vcl_cos(new_lat) - N;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963 void latlong_to_GRS
00964 (double geodetic_lat,
00965 double lon,
00966 double el,
00967 double *x,
00968 double *y,
00969 double *z,
00970 double A,
00971 double B)
00972 {
00973 double geocentric_lat;
00974 double local_radius;
00975 double c, s;
00976
00977 geocentric_lat = geo_detic2centric(geodetic_lat, A, B);
00978
00979
00980 s = vcl_sin(geocentric_lat);
00981 c = vcl_cos(geocentric_lat);
00982
00983
00984
00985 local_radius = (A*B) / vcl_sqrt(B*B*c*c + A*A*s*s);
00986
00987 *x = (local_radius*c + el*vcl_cos(geodetic_lat))*vcl_cos(lon);
00988 *y = (local_radius*c + el*vcl_cos(geodetic_lat))*vcl_sin(lon);
00989 *z = (local_radius*s + el*vcl_sin(geodetic_lat));
00990
00991 #ifdef DEBUG_DATUM
00992 double tlat, tlon, tel;
00993 GRS_to_latlong(*x, *y, *z, &tlat, &tlon, &tel, A, B);
00994 vcl_cout << "Error in computation: (" << (tlat-geodetic_lat) << ", " << (tlon-lon) << ", " << (tel-el) << ")\n";
00995 #endif
00996 }
00997
00998
00999
01000
01001
01002 void nad27n_to_wgs72
01003 (
01004 double phi,
01005 double lamda,
01006 double height,
01007 double *wgs72_phi,
01008 double *wgs72_lamda,
01009 double *wgs72_hgt)
01010 {
01011 double wgs84_phi, wgs84_lamda, wgs84_hgt;
01012
01013 nad27n_to_wgs84(phi, lamda, height,
01014 &wgs84_phi, &wgs84_lamda, &wgs84_hgt);
01015
01016 wgs84_to_wgs72(wgs84_phi, wgs84_lamda, wgs84_hgt,
01017 wgs72_phi, wgs72_lamda, wgs72_hgt);
01018 }
01019
01020
01021
01022
01023
01024
01025 void wgs72_to_nad27n
01026 (
01027 double phi,
01028 double lamda,
01029 double height,
01030 double *nad27n_phi,
01031 double *nad27n_lamda,
01032 double *nad27n_hgt)
01033 {
01034 double wgs84_phi, wgs84_lamda, wgs84_hgt;
01035
01036 wgs72_to_wgs84(phi, lamda, height,
01037 &wgs84_phi, &wgs84_lamda, &wgs84_hgt);
01038
01039 wgs84_to_nad27n(wgs84_phi, wgs84_lamda, wgs84_hgt,
01040 nad27n_phi, nad27n_lamda, nad27n_hgt);
01041 }
01042