GeoConvert.cpp

Go to the documentation of this file.
00001 /**
00002  * \file GeoConvert.cpp
00003  * \brief Command line utility for geographic coordinate conversions
00004  *
00005  * Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <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 GeoCoords.o MGRS.o UTMUPS.o DMS.o
00010  * TransverseMercator.o PolarStereographic.o
00011  *
00012  * See the <a href="GeoConvert.1.html">man page</a> for usage
00013  * information.
00014  **********************************************************************/
00015 
00016 #include "GeographicLib/GeoCoords.hpp"
00017 #include "GeographicLib/DMS.hpp"
00018 #include <sstream>
00019 #include <iostream>
00020 
00021 #include "GeoConvert.usage"
00022 
00023 int main(int argc, char* argv[]) {
00024   using namespace GeographicLib;
00025   typedef Math::real real;
00026   enum { GEOGRAPHIC, DMS, UTMUPS, MGRS, CONVERGENCE };
00027   int outputmode = GEOGRAPHIC;
00028   int prec = 0;
00029   int zone = UTMUPS::MATCH;
00030   bool centerp = true;
00031 
00032   for (int m = 1; m < argc; ++m) {
00033     std::string arg(argv[m]);
00034     if (arg == "-g")
00035       outputmode = GEOGRAPHIC;
00036     else if (arg == "-d")
00037       outputmode = DMS;
00038     else if (arg == "-u")
00039       outputmode = UTMUPS;
00040     else if (arg == "-m")
00041       outputmode = MGRS;
00042     else if (arg == "-c")
00043       outputmode = CONVERGENCE;
00044     else if (arg == "-n")
00045       centerp = false;
00046     else if (arg == "-p") {
00047       if (++m == argc) return usage(1, true);
00048       std::istringstream str(argv[m]);
00049       char c;
00050       if (!(str >> prec) || (str >> c)) {
00051           std::cerr << "Precision " << argv[m] << " is not a number\n";
00052           return 1;
00053       }
00054     } else if (arg == "-z") {
00055       if (++m == argc) return usage(1, true);
00056       std::string zonestr(argv[m]);
00057       try {
00058         bool northp;
00059         UTMUPS::DecodeZone(zonestr, zone, northp);
00060       }
00061       catch (const std::exception&) {
00062         std::istringstream str(zonestr);
00063         char c;
00064         if (!(str >> zone) || (str >> c)) {
00065           std::cerr << "Zone " << zonestr
00066                     << " is not a number or zone+hemisphere\n";
00067           return 1;
00068         }
00069         if (!(zone >= UTMUPS::MINZONE && zone <= UTMUPS::MAXZONE)) {
00070           std::cerr << "Zone " << zone << " not in [0, 60]\n";
00071           return 1;
00072         }
00073       }
00074     } else if (arg == "-s")
00075       zone = UTMUPS::STANDARD;
00076     else if (arg == "-t")
00077       zone = UTMUPS::UTM;
00078     else if (arg == "--version") {
00079       std::cout
00080         << PROGRAM_NAME
00081         << ": $Id: GeoConvert.cpp 6978 2011-02-21 22:42:11Z karney $\n"
00082         << "GeographicLib version " << GEOGRAPHICLIB_VERSION << "\n";
00083       return 0;
00084     } else
00085       return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00086   }
00087 
00088   GeoCoords p;
00089   std::string s;
00090   std::string os;
00091   int retval = 0;
00092 
00093   while (std::getline(std::cin, s)) {
00094     try {
00095       p.Reset(s, centerp);
00096       p.SetAltZone(zone);
00097       switch (outputmode) {
00098       case GEOGRAPHIC:
00099         os = p.GeoRepresentation(prec);
00100         break;
00101       case DMS:
00102         os = p.DMSRepresentation(prec);
00103         break;
00104       case UTMUPS:
00105         os = p.AltUTMUPSRepresentation(prec);
00106         break;
00107       case MGRS:
00108         os = p.AltMGRSRepresentation(prec);
00109         break;
00110       case CONVERGENCE:
00111         {
00112           real
00113             gamma = p.AltConvergence(),
00114             k = p.AltScale();
00115           os =
00116             DMS::Encode(gamma, std::max(-5, std::min(8, prec)) + 5, DMS::NUMBER)
00117             + " " +
00118             DMS::Encode(k, std::max(-5, std::min(8, prec)) + 7, DMS::NUMBER);
00119         }
00120       }
00121     }
00122     catch (const std::exception& e) {
00123       // Write error message cout so output lines match input lines
00124       os = std::string("ERROR: ") + e.what();
00125       retval = 1;
00126     }
00127     std::cout << os << "\n";
00128   }
00129   return retval;
00130 }