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, 2009, 2010) <charles@karney.com>
00006  * and licensed under the LGPL.  For more information, see
00007  * http://geographiclib.sourceforge.net/
00008  *
00009  * Compile with -I../include and link with TransverseMercatorExact.o
00010  * EllipticFunction.o TransverseMercator.o
00011  *
00012  * See \ref transversemercatortest for usage information.
00013  **********************************************************************/
00014 
00015 #include "GeographicLib/EllipticFunction.hpp"
00016 #include "GeographicLib/TransverseMercatorExact.hpp"
00017 #include "GeographicLib/TransverseMercator.hpp"
00018 #include "GeographicLib/DMS.hpp"
00019 #include <iostream>
00020 #include <sstream>
00021 #include <iomanip>
00022 
00023 int usage(int retval) {
00024   ( retval ? std::cerr : std::cout ) <<
00025 "TransverseMercatorTest [-r] [-t|-s]\n\
00026 $Id: TransverseMercatorTest.cpp 6827 2010-05-20 19:56:18Z karney $\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 (or DMS) and meters.\n\
00033 \n\
00034 By default, the WGS84 is ellipsoid is used, central meridian = 0, UTM\n\
00035 central scale (0.9996), 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   using namespace GeographicLib;
00062   typedef Math::real real;
00063   bool reverse = false, testing = false, series = false;
00064   for (int m = 1; m < argc; ++m) {
00065     std::string arg(argv[m]);
00066     if (arg == "-r")
00067       reverse = true;
00068     else if (arg == "-t") {
00069       testing = true;
00070       series = false;
00071     } else if (arg == "-s") {
00072       testing = false;
00073       series = true;
00074     } else
00075       return usage(arg != "-h");
00076   }
00077 
00078   real e, a;
00079   if (testing) {
00080     e = real(0.1L);
00081     EllipticFunction temp(e * e);
00082     a = 1/temp.E();
00083   }
00084   const TransverseMercatorExact& TME = testing ?
00085     TransverseMercatorExact(a, (std::sqrt(1 - e * e) + 1) / (e * e),
00086                             real(1), true) :
00087     TransverseMercatorExact::UTM;
00088 
00089   const TransverseMercator& TMS = TransverseMercator::UTM;
00090 
00091   std::string s;
00092   int retval = 0;
00093   std::cout << std::setprecision(16);
00094   while (std::getline(std::cin, s)) {
00095     try {
00096       std::istringstream str(s);
00097       real lat, lon, x, y;
00098       std::string stra, strb;
00099       if (!(str >> stra >> strb))
00100           throw GeographicErr("Incomplete input: " + s);
00101       if (reverse) {
00102         x = DMS::Decode(stra);
00103         y = DMS::Decode(strb);
00104       } else
00105         DMS::DecodeLatLon(stra, strb, lat, lon);
00106       std::string strc;
00107       if (str >> strc)
00108         throw GeographicErr("Extraneous input: " + strc);
00109       real gamma, k;
00110       if (reverse) {
00111         if (series)
00112           TMS.Reverse(real(0), x, y, lat, lon, gamma, k);
00113         else
00114           TME.Reverse(real(0), x, y, lat, lon, gamma, k);
00115       } else {
00116         if (series)
00117           TMS.Forward(real(0), lat, lon, x, y, gamma, k);
00118         else
00119           TME.Forward(real(0), lat, lon, x, y, gamma, k);
00120       }
00121       std::cout << lat << " " << lon << " " << x << " " << y << " "
00122                 << gamma << " " << k << "\n";
00123     }
00124     catch (const std::exception& e) {
00125       std::cout << "ERROR: " << e.what() << "\n";
00126       retval = 1;
00127     }
00128   }
00129 
00130   return retval;
00131 }

Generated on 21 May 2010 for GeographicLib by  doxygen 1.6.1