47 #define PI                3.14159265358979323e0 
   48 #define PI_OVER_2         (PI/2.0e0) 
   49 #define MAX_DELTA_LONG    ((PI * 70)/180.0) 
   50 #define MIN_SCALE_FACTOR   0.1 
   51 #define MAX_SCALE_FACTOR  10.0 
   54 TransverseMercator::TransverseMercator(
 
   55    double ellipsoidSemiMajorAxis,
 
   56    double ellipsoidFlattening,
 
   57    double centralMeridian,
 
   58    double latitudeOfTrueScale,
 
   62    char   *ellipsoidCode) :
 
   64    TranMerc_Origin_Long( centralMeridian ),
 
   65    TranMerc_Origin_Lat( latitudeOfTrueScale ),
 
   66    TranMerc_False_Easting( falseEasting ),
 
   67    TranMerc_False_Northing( falseNorthing ),
 
   68    TranMerc_Scale_Factor( scaleFactor  ),
 
   69    TranMerc_Delta_Easting(  20000000.0 ),
 
   70    TranMerc_Delta_Northing( 10000000.0 )
 
   73    double invFlattening = 1.0 / ellipsoidFlattening;
 
   75    strcpy( ellipsCode, ellipsoidCode );
 
   77    if (ellipsCode[0] == 
'\0')
 
   81    if (ellipsoidSemiMajorAxis <= 0.0)
 
   85    if ( invFlattening < 150 )
 
   93    if ((centralMeridian < -
PI) || (centralMeridian > (2*
PI)))
 
  102    if (TranMerc_Origin_Long > 
PI)
 
  103       TranMerc_Origin_Long -= (2*
PI);
 
  110    generateCoefficients(
 
  111       invFlattening, n1, TranMerc_aCoeff, TranMerc_bCoeff, R4oa, ellipsCode );
 
  113    TranMerc_K0R4    = R4oa * TranMerc_Scale_Factor * ellipsoidSemiMajorAxis;
 
  114    TranMerc_K0R4inv = 1.0 / TranMerc_K0R4;
 
  135       TranMerc_eps            = tm.TranMerc_eps;
 
  137       TranMerc_K0R4           = tm.TranMerc_K0R4;
 
  138       TranMerc_K0R4inv        = tm.TranMerc_K0R4inv;
 
  142          TranMerc_aCoeff[i] = tm.TranMerc_aCoeff[i];
 
  143          TranMerc_bCoeff[i] = tm.TranMerc_bCoeff[i];
 
  146       TranMerc_Origin_Long    = tm.TranMerc_Origin_Long; 
 
  147       TranMerc_Origin_Lat     = tm.TranMerc_Origin_Lat; 
 
  148       TranMerc_False_Easting  = tm.TranMerc_False_Easting; 
 
  149       TranMerc_False_Northing = tm.TranMerc_False_Northing; 
 
  150       TranMerc_Scale_Factor   = tm.TranMerc_Scale_Factor;
 
  152       TranMerc_Delta_Easting  = tm.TranMerc_Delta_Easting; 
 
  153       TranMerc_Delta_Northing = tm.TranMerc_Delta_Northing; 
 
  164       TranMerc_Origin_Long, TranMerc_Origin_Lat, TranMerc_Scale_Factor,
 
  165       TranMerc_False_Easting, TranMerc_False_Northing );
 
  172    double longitude = geodeticCoordinates->
longitude();
 
  173    double latitude  = geodeticCoordinates->
latitude();
 
  176       longitude -= (2 * 
PI);
 
  178       longitude += (2 * 
PI);
 
  183    double lambda  = longitude - TranMerc_Origin_Long;
 
  188    checkLatLon( latitude, lambda );
 
  190    double easting, northing;
 
  191    latLonToNorthingEasting( latitude, longitude, northing, easting );
 
  195    double falseEasting, falseNorthing;
 
  196    latLonToNorthingEasting(
 
  197       TranMerc_Origin_Lat, TranMerc_Origin_Long, falseNorthing, falseEasting );
 
  199    easting  += TranMerc_False_Easting  - falseEasting;
 
  200    northing += TranMerc_False_Northing - falseNorthing;
 
  202    char warning[256] = 
"";
 
  205    if( invFlattening < 290.0 || invFlattening > 301.0 )
 
  207          "Eccentricity is outside range that algorithm accuracy has been tested." );
 
  214 void TransverseMercator::latLonToNorthingEasting( 
 
  215    const double &latitude,
 
  216    const double &longitude,
 
  223    double lambda  = longitude - TranMerc_Origin_Long;
 
  228    checkLatLon( latitude, lambda );
 
  230    double cosLam = cos(lambda);
 
  231    double sinLam = sin(lambda);
 
  232    double cosPhi = cos(latitude);
 
  233    double sinPhi = sin(latitude);
 
  235    double P, part1, part2, denom, cosChi, sinChi;
 
  245    P      = exp(TranMerc_eps * aTanH(TranMerc_eps * sinPhi));
 
  246    part1  = (1 + sinPhi) / P;
 
  247    part2  = (1 - sinPhi) * P;
 
  248    denom  = part1 + part2;
 
  249    cosChi = 2 * cosPhi / denom;
 
  250    sinChi = (part1 - part2) / denom;
 
  256    U = aTanH(cosChi * sinLam);
 
  257    V = atan2(sinChi, cosChi * cosLam);
 
  260    computeHyperbolicSeries( 2.0 * U, c2ku, s2ku );
 
  261    computeTrigSeries( 2.0 * V, c2kv, s2kv );
 
  268    for (
int k = 
N_TERMS - 1; k >= 0; k--)
 
  270       xStar += TranMerc_aCoeff[k] * s2ku[k] * c2kv[k];
 
  271       yStar += TranMerc_aCoeff[k] * c2ku[k] * s2kv[k];
 
  278    easting  = (TranMerc_K0R4 * xStar);
 
  279    northing = (TranMerc_K0R4 * yStar);
 
  286    double easting  = mapProjectionCoordinates->
easting();
 
  287    double northing = mapProjectionCoordinates->
northing();
 
  289    if (  (easting < (TranMerc_False_Easting - TranMerc_Delta_Easting))
 
  290        ||(easting > (TranMerc_False_Easting + TranMerc_Delta_Easting)))
 
  295    if (   (northing < (TranMerc_False_Northing - TranMerc_Delta_Northing))
 
  296        || (northing > (TranMerc_False_Northing + TranMerc_Delta_Northing)))
 
  301    double longitude, latitude;
 
  304    double falseEasting, falseNorthing;
 
  305    latLonToNorthingEasting(
 
  306       TranMerc_Origin_Lat, TranMerc_Origin_Long, falseNorthing, falseEasting );
 
  308    easting  -= (TranMerc_False_Easting  - falseEasting);
 
  309    northing -= (TranMerc_False_Northing - falseNorthing);
 
  311    northingEastingToLatLon( northing, easting, latitude, longitude );
 
  313    longitude = (longitude >   
PI) ? longitude - (2 * 
PI): longitude;
 
  314    longitude = (longitude <= -
PI) ? longitude + (2 * 
PI): longitude;
 
  316    if(fabs(latitude) > (90.0 * 
PI / 180.0))
 
  320    if((longitude) > (
PI))
 
  322       longitude -= (2 * 
PI);
 
  323       if(fabs(longitude) > 
PI)
 
  326    else if((longitude) < (-
PI))
 
  328       longitude += (2 * 
PI);
 
  329       if(fabs(longitude) > 
PI)
 
  336    if( invFlattening < 290.0 || invFlattening > 301.0 )
 
  338          "Eccentricity is outside range that algorithm accuracy has been tested." );
 
  344 void TransverseMercator::northingEastingToLatLon( 
 
  345    const double &northing,
 
  346    const double &easting,
 
  357    double xStar = TranMerc_K0R4inv * (easting);
 
  358    double yStar = TranMerc_K0R4inv * (northing);
 
  361    computeHyperbolicSeries( 2.0 * xStar, c2kx, s2kx );
 
  362    computeTrigSeries( 2.0 * yStar, c2ky, s2ky );
 
  369    for (
int k = 
N_TERMS - 1; k >= 0; k--)
 
  371       U += TranMerc_bCoeff[k] * s2kx[k] * c2ky[k];
 
  372       V += TranMerc_bCoeff[k] * c2kx[k] * s2ky[k];
 
  380    double coshU = cosh(U);
 
  381    double sinhU = sinh(U);
 
  382    double cosV  = cos(V);
 
  383    double sinV  = sin(V);
 
  386    if ((fabs(cosV) < 10E-12) && (fabs(coshU) < 10E-12))
 
  389       lambda = atan2(sinhU, cosV);
 
  392    sinChi = sinV / coshU;
 
  393    latitude = geodeticLat( sinChi, TranMerc_eps );
 
  397    longitude = TranMerc_Origin_Long + lambda;
 
  402 void TransverseMercator::generateCoefficients(
 
  406     double  bCoeff[MAX_TERMS],
 
  444    double n2, n3, n4, n5, n6, n7, n8, n9, n10, coeff;
 
  446    n1  = 1.0 / (2*invfla - 1.0);
 
  462    if (( strcmp( ellipsoidCode, 
"AA") == 0) || (strcmp(ellipsoidCode, 
"AM") == 0))
 
  464        aCoeff[0] = 8.3474517669594013740e-04;
 
  465        aCoeff[1] = 7.554352936725572895e-07;
 
  466        aCoeff[2] = 1.18487391005135489e-09;
 
  467        aCoeff[3] = 2.3946872955703565e-12;
 
  468        aCoeff[4] = 5.610633978440270e-15;
 
  469        aCoeff[5] = 1.44858956458553e-17;
 
  471        bCoeff[0] = -8.3474551646761162264e-04;
 
  472        bCoeff[1] = -5.863630361809676570e-08;
 
  473        bCoeff[2] = -1.65562038746920803e-10;
 
  474        bCoeff[3] = -2.1340335537652749e-13;
 
  475        bCoeff[4] = -3.720760760132477e-16;
 
  476        bCoeff[5] = -7.08304328877781e-19;
 
  478    else if (( strcmp( ellipsoidCode, 
"EA") == 0) || ( strcmp( ellipsoidCode, 
"EB") == 0) ||
 
  479             ( strcmp( ellipsoidCode, 
"EC") == 0) || ( strcmp( ellipsoidCode, 
"ED") == 0) ||
 
  480             ( strcmp( ellipsoidCode, 
"EE") == 0))
 
  482            aCoeff[0] = 8.3064943111192510534e-04;
 
  483            aCoeff[1] = 7.480375027595025021e-07;
 
  484            aCoeff[2] = 1.16750772278215999e-09;
 
  485            aCoeff[3] = 2.3479972304395461e-12;
 
  486            aCoeff[4] = 5.474212231879573e-15;
 
  487            aCoeff[5] = 1.40642257446745e-17;
 
  489            bCoeff[0] = -8.3064976590443772201e-04;
 
  490            bCoeff[1] = -5.805953517555717859e-08;
 
  491            bCoeff[2] = -1.63133251663416522e-10;
 
  492            bCoeff[3] = -2.0923797199593389e-13;
 
  493            bCoeff[4] = -3.630200927775259e-16;
 
  494            bCoeff[5] =  -6.87666654919219e-19;
 
  496    else if (( strcmp( ellipsoidCode, 
"BN") == 0) || ( strcmp( ellipsoidCode, 
"BR") == 0))
 
  498             aCoeff[0] = 8.3522527226849818552e-04;
 
  499             aCoeff[1] = 7.563048340614894422e-07;
 
  500             aCoeff[2] = 1.18692075307408346e-09;
 
  501             aCoeff[3] = 2.4002054791393298e-12;
 
  502             aCoeff[4] = 5.626801597980756e-15;
 
  503             aCoeff[5] = 1.45360057224474e-17;
 
  505             bCoeff[0] = -8.3522561262703079182e-04;
 
  506             bCoeff[1] = -5.870409978661008580e-08;
 
  507             bCoeff[2] = -1.65848307463131468e-10;
 
  508             bCoeff[3] = -2.1389565927064571e-13;
 
  509             bCoeff[4] = -3.731493368666479e-16;
 
  510             bCoeff[5] = -7.10756898071999e-19;
 
  512    else if (( strcmp( ellipsoidCode, 
"KA") == 0) || ( strcmp( ellipsoidCode, 
"HE") == 0) ||
 
  513             ( strcmp( ellipsoidCode, 
"FA") == 0))
 
  515             aCoeff[0] = 8.3761175713442343106e-04;
 
  516             aCoeff[1] = 7.606346200814720197e-07;
 
  517             aCoeff[2] = 1.19713032035541037e-09;
 
  518             aCoeff[3] = 2.4277772986483520e-12;
 
  519             aCoeff[4] = 5.707722772225013e-15;
 
  520             aCoeff[5] = 1.47872454335773e-17;
 
  522             bCoeff[0] = -8.3761210042019176501e-04;
 
  523             bCoeff[1] = -5.904169154078546237e-08;
 
  524             bCoeff[2] = -1.67276212891429215e-10;
 
  525             bCoeff[3] = -2.1635549847939549e-13;
 
  526             bCoeff[4] = -3.785212121016612e-16;
 
  527             bCoeff[5] = -7.23053625983667e-19;
 
  530    else if ( strcmp( ellipsoidCode, 
"WD") == 0) 
 
  532             aCoeff[0] = 8.3772481044362217923e-04;
 
  533             aCoeff[1] = 7.608400388863560936e-07;
 
  534             aCoeff[2] = 1.19761541904924067e-09;
 
  535             aCoeff[3] = 2.4290893081322466e-12;
 
  536             aCoeff[4] = 5.711579173743133e-15;
 
  537             aCoeff[5] = 1.47992364667635e-17;
 
  539             bCoeff[0] = -8.3772515386847544554e-04;
 
  540             bCoeff[1] = -5.905770828762463028e-08;
 
  541             bCoeff[2] = -1.67344058948464124e-10;
 
  542             bCoeff[3] = -2.1647255130188214e-13;
 
  543             bCoeff[4] = -3.787772179729998e-16;
 
  544             bCoeff[5] = -7.23640523525528e-19;
 
  546    else if ( strcmp( ellipsoidCode, 
"WE") == 0)
 
  548             aCoeff[0] = 8.3773182062446983032e-04;
 
  549             aCoeff[1] = 7.608527773572489156e-07;
 
  550             aCoeff[2] = 1.19764550324249210e-09;
 
  551             aCoeff[3] = 2.4291706803973131e-12;
 
  552             aCoeff[4] = 5.711818369154105e-15;
 
  553             aCoeff[5] = 1.47999802705262e-17;
 
  555             bCoeff[0] = -8.3773216405794867707e-04;
 
  556             bCoeff[1] = -5.905870152220365181e-08;
 
  557             bCoeff[2] = -1.67348266534382493e-10;
 
  558             bCoeff[3] = -2.1647981104903862e-13;
 
  559             bCoeff[4] = -3.787930968839601e-16;
 
  560             bCoeff[5] = -7.23676928796690e-19;
 
  562    else if ( strcmp( ellipsoidCode, 
"RF") == 0)       
 
  564             aCoeff[0] = 8.3773182472855134012e-04;
 
  565             aCoeff[1] = 7.608527848149655006e-07;
 
  566             aCoeff[2] = 1.19764552085530681e-09;
 
  567             aCoeff[3] = 2.4291707280369697e-12;
 
  568             aCoeff[4] = 5.711818509192422e-15;
 
  569             aCoeff[5] = 1.47999807059922e-17;
 
  571             bCoeff[0] = -8.3773216816203523672e-04;
 
  572             bCoeff[1] = -5.905870210369121594e-08;
 
  573             bCoeff[2] = -1.67348268997717031e-10;
 
  574             bCoeff[3] = -2.1647981529928124e-13;
 
  575             bCoeff[4] = -3.787931061803592e-16;
 
  576             bCoeff[5] = -7.23676950110361e-19;
 
  579    else if (( strcmp( ellipsoidCode, 
"SA") == 0) || ( strcmp( ellipsoidCode, 
"AN") == 0))
 
  581             aCoeff[0] = 8.3775209887947194075e-04;
 
  582             aCoeff[1] = 7.608896263599627157e-07;
 
  583             aCoeff[2] = 1.19773253021831769e-09;
 
  584             aCoeff[3] = 2.4294060763606098e-12;
 
  585             aCoeff[4] = 5.712510331613028e-15;
 
  586             aCoeff[5] = 1.48021320370432e-17;
 
  588             bCoeff[0] = -8.3775244233790270051e-04;
 
  589             bCoeff[1] = -5.906157468586898015e-08;
 
  590             bCoeff[2] = -1.67360438158764851e-10;
 
  591             bCoeff[3] = -2.1650081225048788e-13;
 
  592             bCoeff[4] = -3.788390325953455e-16;
 
  593             bCoeff[5] = -7.23782246429908e-19; 
 
  595    else if ( strcmp( ellipsoidCode, 
"ID") == 0)
 
  597             aCoeff[0] = 8.3776052087969078729e-04;
 
  598             aCoeff[1] = 7.609049308144604484e-07;
 
  599             aCoeff[2] = 1.19776867565343872e-09;
 
  600             aCoeff[3] = 2.4295038464530901e-12;
 
  601             aCoeff[4] = 5.712797738386076e-15;
 
  602             aCoeff[5] = 1.48030257891140e-17;
 
  604             bCoeff[0] = -8.3776086434848497443e-04;
 
  605             bCoeff[1] = -5.906276799395007586e-08;
 
  606             bCoeff[2] = -1.67365493472742884e-10;
 
  607             bCoeff[3] = -2.1650953495573773e-13;
 
  608             bCoeff[4] = -3.788581120060625e-16;
 
  609             bCoeff[5] = -7.23825990889693e-19;
 
  611    else if (( strcmp( ellipsoidCode, 
"IN") == 0) || ( strcmp( ellipsoidCode, 
"HO") == 0))
 
  613             aCoeff[0] = 8.4127599100356448089e-04;
 
  614             aCoeff[1] = 7.673066923431950296e-07;
 
  615             aCoeff[2] = 1.21291995794281190e-09;
 
  616             aCoeff[3] = 2.4705731165688123e-12;
 
  617             aCoeff[4] = 5.833780550286833e-15;
 
  618             aCoeff[5] = 1.51800420867708e-17;
 
  620             bCoeff[0] = -8.4127633881644851945e-04;
 
  621             bCoeff[1] = -5.956193574768780571e-08;
 
  622             bCoeff[2] = -1.69484573979154433e-10;
 
  623             bCoeff[3] = -2.2017363465021880e-13;
 
  624             bCoeff[4] = -3.868896221495780e-16;
 
  625             bCoeff[5] = -7.42279219864412e-19;
 
  628    else if ( strcmp( ellipsoidCode, 
"WO") == 0)
 
  630             aCoeff[0] = 8.4411652150600103279e-04;
 
  631             aCoeff[1] = 7.724989750172583427e-07;
 
  632             aCoeff[2] = 1.22525529789972041e-09;
 
  633             aCoeff[3] = 2.5041361775549209e-12;
 
  634             aCoeff[4] = 5.933026083631383e-15;
 
  635             aCoeff[5] = 1.54904908794521e-17;
 
  637             bCoeff[0] = -8.4411687285559594196e-04;
 
  638             bCoeff[1] = -5.996681687064322548e-08;
 
  639             bCoeff[2] = -1.71209836918814857e-10;
 
  640             bCoeff[3] = -2.2316811233502163e-13;
 
  641             bCoeff[4] = -3.934782433323038e-16;
 
  642             bCoeff[5] = -7.57474665717687e-19;
 
  645    else if ( strcmp( ellipsoidCode, 
"CC") == 0)
 
  647             aCoeff[0] = 8.4703742793654652315e-04;
 
  648             aCoeff[1] = 7.778564517658115212e-07;
 
  649             aCoeff[2] = 1.23802665917879731e-09;
 
  650             aCoeff[3] = 2.5390045684252928e-12;
 
  651             aCoeff[4] = 6.036484469753319e-15;
 
  652             aCoeff[5] = 1.58152259295850e-17;
 
  654             bCoeff[0] = -8.4703778294785813001e-04;
 
  655             bCoeff[1] = -6.038459874600183555e-08;
 
  656             bCoeff[2] = -1.72996106059227725e-10;
 
  657             bCoeff[3] = -2.2627911073545072e-13;
 
  658             bCoeff[4] = -4.003466873888566e-16;
 
  659             bCoeff[5] = -7.73369749524777e-19;
 
  663    else if ( strcmp( ellipsoidCode, 
"CG") == 0)
 
  665             aCoeff[0] = 8.5140099460764136776e-04;
 
  666             aCoeff[1] = 7.858945456038187774e-07;
 
  667             aCoeff[2] = 1.25727085106103462e-09;
 
  668             aCoeff[3] = 2.5917718627340128e-12;
 
  669             aCoeff[4] = 6.193726879043722e-15;
 
  670             aCoeff[5] = 1.63109098395549e-17;
 
  672             bCoeff[0] = -8.5140135513650084564e-04;
 
  673             bCoeff[1] = -6.101145475063033499e-08;
 
  674             bCoeff[2] = -1.75687742410879760e-10;
 
  675             bCoeff[3] = -2.3098718484594067e-13;
 
  676             bCoeff[4] = -4.107860472919190e-16;
 
  677             bCoeff[5] = -7.97633133452512e-19;
 
  680    else if ( strcmp( ellipsoidCode, 
"CD") == 0)
 
  682             aCoeff[0] = 8.5140395445291970541e-04;
 
  683             aCoeff[1] = 7.859000119464140978e-07;
 
  684             aCoeff[2] = 1.25728397182445579e-09;
 
  685             aCoeff[3] = 2.5918079321459932e-12;
 
  686             aCoeff[4] = 6.193834639108787e-15;
 
  687             aCoeff[5] = 1.63112504092335e-17;
 
  689             bCoeff[0] = -8.5140431498554106268e-04;
 
  690             bCoeff[1] = -6.101188106187092184e-08;
 
  691             bCoeff[2] = -1.75689577596504470e-10;
 
  692             bCoeff[3] = -2.3099040312610703e-13;
 
  693             bCoeff[4] = -4.107932016207395e-16;
 
  694             bCoeff[5] = -7.97649804397335e-19;
 
  703     coeff += (-18975107.0) * n8 / 50803200.0;
 
  704     coeff += (72161.0)     * n7 / 387072.0;
 
  705     coeff += (7891.0)      * n6 / 37800.0;
 
  706     coeff += (-127.0)      * n5 / 288.0;
 
  707     coeff += (41.0)        * n4 / 180.0;
 
  708     coeff += (5.0)         * n3 / 16.0;
 
  709     coeff += (-2.0)        * n2 / 3.0;
 
  710     coeff += (1.0)         * n1 / 2.0;
 
  716     coeff += (148003883.0) * n8 / 174182400.0;
 
  717     coeff += (13769.0)     * n7 / 28800.0;
 
  718     coeff += (-1983433.0)  * n6 / 1935360.0;
 
  719     coeff += (281.0)       * n5 / 630.0;
 
  720     coeff += (557.0)       * n4 / 1440.0;
 
  721     coeff += (-3.0)        * n3 / 5.0;
 
  722     coeff += (13.0)        * n2 / 48.0;
 
  728     coeff += (79682431.0)  * n8 / 79833600.0;
 
  729     coeff += (-67102379.0) * n7 / 29030400.0;
 
  730     coeff += (167603.0)    * n6 / 181440.0;
 
  731     coeff += (15061.0)     * n5 / 26880.0;
 
  732     coeff += (-103.0)      * n4 / 140.0;
 
  733     coeff += (61.0)        * n3 / 240.0;
 
  739     coeff += (-40176129013.0) * n8 / 7664025600.0;
 
  740     coeff += (97445.0)        * n7 / 49896.0;
 
  741     coeff += (6601661.0)      * n6 / 7257600.0;
 
  742     coeff += (-179.0)         * n5 / 168.0;
 
  743     coeff += (49561.0)        * n4 / 161280.0;
 
  749     coeff += (2605413599.0) * n8 / 622702080.0;
 
  750     coeff += (14644087.0)   * n7 / 9123840.0;
 
  751     coeff += (-3418889.0)   * n6 / 1995840.0;
 
  752     coeff += (34729.0)      * n5 / 80640.0;
 
  758     coeff += (175214326799.0) * n8 / 58118860800.0;
 
  759     coeff += (-30705481.0)    * n7 / 10378368.0;
 
  760     coeff += (212378941.0)    * n6 / 319334400.0;
 
  766     coeff += (-16759934899.0) * n8 / 3113510400.0;
 
  767     coeff += (1522256789.0)   * n7 / 1383782400.0;
 
  773     coeff += (1424729850961.0) * n8 / 743921418240.0;
 
  779     coeff += (-7944359.0) * n8 / 67737600.0;
 
  780     coeff += (5406467.0)  * n7 / 38707200.0;
 
  781     coeff += (-96199.0)   * n6 / 604800.0;
 
  782     coeff += (81.0)       * n5 / 512.0;
 
  783     coeff += (1.0)        * n4 / 360.0;
 
  784     coeff += (-37.0)      * n3 / 96.0;
 
  785     coeff += (2.0)        * n2 / 3.0;
 
  786     coeff += (-1.0)       * n1 / 2.0;
 
  792     coeff += (-24749483.0) * n8 / 348364800.0;
 
  793     coeff += (-51841.0)    * n7 / 1209600.0;
 
  794     coeff += (1118711.0)   * n6 / 3870720.0;
 
  795     coeff += (-46.0)       * n5 / 105.0;
 
  796     coeff += (437.0)       * n4 / 1440.0;
 
  797     coeff += (-1.0)        * n3 / 15.0;
 
  798     coeff += (-1.0)        * n2 / 48.0;
 
  804     coeff += (6457463.0)  * n8 / 17740800.0;
 
  805     coeff += (-9261899.0) * n7 / 58060800.0;
 
  806     coeff += (-5569.0)    * n6 / 90720.0;
 
  807     coeff += (209.0)      * n5 / 4480.0;
 
  808     coeff += (37.0)       * n4 / 840.0;
 
  809     coeff += (-17.0)      * n3 / 480.0;
 
  815     coeff += (-324154477.0) * n8 / 7664025600.0;
 
  816     coeff += (-466511.0)    * n7 / 2494800.0;
 
  817     coeff += (830251.0)     * n6 / 7257600.0;
 
  818     coeff += (11.0)         * n5 / 504.0;
 
  819     coeff += (-4397.0)      * n4 / 161280.0;
 
  825     coeff += (-22894433.0) * n8 / 124540416.0;
 
  826     coeff += (8005831.0)   * n7 / 63866880.0;
 
  827     coeff += (108847.0)    * n6 / 3991680.0;
 
  828     coeff += (-4583.0)     * n5 / 161280.0;
 
  834     coeff += (2204645983.0) * n8 / 12915302400.0;
 
  835     coeff += (16363163.0)   * n7 / 518918400.0;
 
  836     coeff += (-20648693.0)  * n6 / 638668800.0;
 
  842     coeff += (497323811.0)  * n8 / 12454041600.0;
 
  843     coeff += (-219941297.0) * n7 / 5535129600.0;
 
  849     coeff += (-191773887257.0) * n8 / 3719607091200.0;
 
  855    coeff += 49 * n10 / 65536.0;
 
  856    coeff += 25 * n8 / 16384.0;
 
  861    R4oa = coeff / (1 + n1);
 
  865 void TransverseMercator::checkLatLon( 
double latitude, 
double deltaLon )
 
  869       deltaLon -= (2 * 
PI);
 
  871       deltaLon += (2 * 
PI);
 
  873    double testAngle = fabs( deltaLon );
 
  875    double delta = fabs( deltaLon - 
PI );
 
  876    if( delta < testAngle )
 
  879    delta = fabs( deltaLon + 
PI );
 
  880    if( delta < testAngle )
 
  885    if( delta < testAngle )
 
  889    if( delta < testAngle )
 
  899 double TransverseMercator::aTanH(
double x)
 
  901     return(0.5 * log((1 + x) / (1 - x)));
 
  905 double TransverseMercator::geodeticLat(
 
  911    double s_old = 1.0e99;
 
  913    double onePlusSinChi  = 1.0+sinChi;
 
  914    double oneMinusSinChi = 1.0-sinChi;
 
  916    for( 
int n = 0; n < 30; n++ )
 
  918       p = exp( e * aTanH( e * s ) );
 
  920       s = ( onePlusSinChi * pSq - oneMinusSinChi ) 
 
  921          /( onePlusSinChi * pSq + oneMinusSinChi );
 
  923       if( fabs( s - s_old ) < 1.0e-12 )
 
  932 void TransverseMercator::computeHyperbolicSeries(
 
  939    c2kx[0] = cosh(twoX);
 
  940    s2kx[0] = sinh(twoX);
 
  941    c2kx[1] = 2.0 * c2kx[0] * c2kx[0] - 1.0;
 
  942    s2kx[1] = 2.0 * c2kx[0] * s2kx[0];
 
  943    c2kx[2] = c2kx[0] * c2kx[1] + s2kx[0] * s2kx[1];
 
  944    s2kx[2] = c2kx[1] * s2kx[0] + c2kx[0] * s2kx[1];
 
  945    c2kx[3] = 2.0 * c2kx[1] * c2kx[1] - 1.0;
 
  946    s2kx[3] = 2.0 * c2kx[1] * s2kx[1];
 
  947    c2kx[4] = c2kx[0] * c2kx[3] + s2kx[0] * s2kx[3];
 
  948    s2kx[4] = c2kx[3] * s2kx[0] + c2kx[0] * s2kx[3];
 
  949    c2kx[5] = 2.0 * c2kx[2] * c2kx[2] - 1.0;
 
  950    s2kx[5] = 2.0 * c2kx[2] * s2kx[2];
 
  951    c2kx[6] = c2kx[0] * c2kx[5] + s2kx[0] * s2kx[5];
 
  952    s2kx[6] = c2kx[5] * s2kx[0] + c2kx[0] * s2kx[5];
 
  953    c2kx[7] = 2.0 * c2kx[3] * c2kx[3] - 1.0;
 
  954    s2kx[7] = 2.0 * c2kx[3] * s2kx[3];
 
  957 void TransverseMercator::computeTrigSeries(
 
  966    c2ky[1] = 2.0 * c2ky[0] * c2ky[0] - 1.0;
 
  967    s2ky[1] = 2.0 * c2ky[0] * s2ky[0];
 
  968    c2ky[2] = c2ky[1] * c2ky[0] - s2ky[1] * s2ky[0];
 
  969    s2ky[2] = c2ky[1] * s2ky[0] + c2ky[0] * s2ky[1];
 
  970    c2ky[3] = 2.0 * c2ky[1] * c2ky[1] - 1.0;
 
  971    s2ky[3] = 2.0 * c2ky[1] * s2ky[1];
 
  972    c2ky[4] = c2ky[3] * c2ky[0] - s2ky[3] * s2ky[0];
 
  973    s2ky[4] = c2ky[3] * s2ky[0] + c2ky[0] * s2ky[3];
 
  974    c2ky[5] = 2.0 * c2ky[2] * c2ky[2] - 1.0;
 
  975    s2ky[5] = 2.0 * c2ky[2] * s2ky[2];
 
  976    c2ky[6] = c2ky[5] * c2ky[0] - s2ky[5] * s2ky[0];
 
  977    s2ky[6] = c2ky[5] * s2ky[0] + c2ky[0] * s2ky[5];
 
  978    c2ky[7] = 2.0 * c2ky[3] * c2ky[3] - 1.0;
 
  979    s2ky[7] = 2.0 * c2ky[3] * s2ky[3];