TransverseMercatorTest.cpp
Go to the documentation of this file.
00001 /**
00002  * \file TransverseMercatorTest.cpp
00003  * \brief Command line utility for testing transverse Mercator projections
00004  *
00005  * Copyright (c) Charles Karney (2008) <charles@karney.com>
00006  * http://charles.karney.info/geographic
00007  * and licensed under the LGPL.
00008  *
00009  * Compile with
00010  *
00011  *   g++ -g -O3 -I.. -o TransverseMercatorTest TransverseMercatorTest.cpp TransverseMercatorExact.cpp Constants.cpp EllipticFunction.cpp TransverseMercator.cpp
00012  *
00013  * See \ref transversemercatortest for usage information.
00014  **********************************************************************/
00015 
00016 #include <string>
00017 #include <iostream>
00018 #include <iomanip>
00019 #include "GeographicLib/EllipticFunction.hpp"
00020 #include "GeographicLib/TransverseMercatorExact.hpp"
00021 #include "GeographicLib/TransverseMercator.hpp"
00022 
00023 int usage(int retval) {
00024   ( retval ? std::cerr : std::cout ) <<
00025 "TransverseMercatorTest [-r] [-t|-s]\n\
00026 $Id: TransverseMercatorTest.cpp 6558 2009-02-27 23:42:54Z ckarney $\n\
00027 \n\
00028 Convert between geographic coordinates and transverse Mercator coordinates.\n\
00029 \n\
00030 Read lines with latitude and longitude (or easting and northing if -r is\n\
00031 specified) from standard input and print latitude, longitude, easting,\n\
00032 northing, convergence, and scale.  Units are degrees and meters.\n\
00033 \n\
00034 By default, the WGS84 is ellipsoid is used, central meridian = 0, UTM\n\
00035 central scale, and false easting and false northing are zero.\n\
00036 \n\
00037 If -r is given, the reverse projection is performed (the inputs are easting\n\
00038 and northing).\n\
00039 \n\
00040 If -s is given, the sixth-order Krueger series approximation to the\n\
00041 transverse Mercator projection is used instead of the exact projection.\n\
00042 \n\
00043 If -t is specified, an ellipsoid of eccentricity 0.1 is used, central scale\n\
00044 = 1, 1/4 meridian distance = 1.  In addition, the cut in the exact\n\
00045 transverse Mercator projection at northing = 0 is removed.  The domain of\n\
00046 latitude (lat) and longitude (lon) is the union of\n\
00047     lat in [0, 90]  and lon in [0, 90]\n\
00048     lat in (-90, 0] and lon in [81, 90]\n\
00049 The domain of easting (x) and northing (x) is the union of\n\
00050     x in [0, inf)       and y in [0, 1]\n\
00051     x in [1.71..., inf) and y in (-inf, 0]\n\
00052 \n\
00053 -s and -t are mutually exclusive (the last flag specified is the operative\n\
00054 one).\n\
00055 \n\
00056 -h prints this help.\n";
00057   return retval;
00058 }
00059 
00060 int main(int argc, char* argv[]) {
00061   bool reverse = false, testing = false, series = false;
00062   for (int m = 1; m < argc; ++m) {
00063     std::string arg(argv[m]);
00064     if (arg == "-r")
00065       reverse = true;
00066     else if (arg == "-t") {
00067       testing = true;
00068       series = false;
00069     } else if (arg == "-s") {
00070       testing = false;
00071       series = true;
00072     } else
00073       return usage(arg != "-h");
00074   }
00075 
00076   double e, a;
00077   if (testing) {
00078     e = 0.1;
00079     GeographicLib::EllipticFunction temp(e * e);
00080     a = 1/temp.E();
00081   }
00082   const GeographicLib::TransverseMercatorExact& TME = testing ?
00083     GeographicLib::TransverseMercatorExact
00084     (a, (std::sqrt(1 - e * e) + 1) / (e * e), 1.0, true) :
00085     GeographicLib::TransverseMercatorExact::UTM;
00086 
00087   const GeographicLib::TransverseMercator& TMS =
00088     GeographicLib::TransverseMercator::UTM;
00089 
00090   std::cout << std::setprecision(16);
00091   while (true) {
00092     double lat, lon, x, y;
00093     if (reverse)
00094       std::cin >> x >> y;
00095     else
00096       std::cin >> lat >> lon;
00097     if (!std::cin.good())
00098       break;
00099     double gamma, k;
00100     if (reverse) {
00101       if (series)
00102         TMS.Reverse(0.0, x, y, lat, lon, gamma, k);
00103       else
00104         TME.Reverse(0.0, x, y, lat, lon, gamma, k);
00105     } else {
00106       if (series)
00107         TMS.Forward(0.0, lat, lon, x, y, gamma, k);
00108       else
00109         TME.Forward(0.0, lat, lon, x, y, gamma, k);
00110     }
00111     std::cout << lat << " " << lon << " "
00112               << x << " " << y << " "
00113               << gamma << " " << k << "\n";
00114   }
00115   return 0;
00116 }