CartConvert.cpp

Go to the documentation of this file.
00001 /**
00002  * \file CartConvert.cpp
00003  * \brief Command line utility for geodetic to cartesian coordinate conversions
00004  *
00005  * Copyright (c) Charles Karney (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 Geocentric.o LocalCartesian.o
00010  *
00011  * See the <a href="CartConvert.1.html">man page</a> for usage
00012  * information.
00013  **********************************************************************/
00014 
00015 #include "GeographicLib/Geocentric.hpp"
00016 #include "GeographicLib/LocalCartesian.hpp"
00017 #include "GeographicLib/DMS.hpp"
00018 #include <iostream>
00019 #include <sstream>
00020 
00021 #include "CartConvert.usage"
00022 
00023 int main(int argc, char* argv[]) {
00024   using namespace GeographicLib;
00025   typedef Math::real real;
00026   bool localcartesian = false, reverse = false;
00027   real
00028     a = Constants::WGS84_a<real>(),
00029     r = Constants::WGS84_r<real>();
00030   real lat0 = 0, lon0 = 0, h0 = 0;
00031   for (int m = 1; m < argc; ++m) {
00032     std::string arg(argv[m]);
00033     if (arg == "-r")
00034       reverse = true;
00035     else if (arg == "-l") {
00036       localcartesian = true;
00037       if (m + 3 >= argc) return usage(1, true);
00038       try {
00039         DMS::DecodeLatLon(std::string(argv[m + 1]), std::string(argv[m + 2]),
00040                           lat0, lon0);
00041         h0 = DMS::Decode(std::string(argv[m + 3]));
00042       }
00043       catch (const std::exception& e) {
00044         std::cerr << "Error decoding arguments of -l: " << e.what() << "\n";
00045         return 1;
00046       }
00047       m += 3;
00048     } else if (arg == "-e") {
00049       if (m + 2 >= argc) return usage(1, true);
00050       try {
00051         a = DMS::Decode(std::string(argv[m + 1]));
00052         r = DMS::Decode(std::string(argv[m + 2]));
00053       }
00054       catch (const std::exception& e) {
00055         std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";
00056         return 1;
00057       }
00058       m += 2;
00059     } else if (arg == "--version") {
00060       std::cout
00061         << PROGRAM_NAME
00062         << ": $Id: CartConvert.cpp 6978 2011-02-21 22:42:11Z karney $\n"
00063         << "GeographicLib version " << GEOGRAPHICLIB_VERSION << "\n";
00064       return 0;
00065     } else
00066       return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00067   }
00068 
00069   const Geocentric ec(a, r);
00070   const LocalCartesian lc(lat0, lon0, h0, ec);
00071 
00072   std::string s;
00073   int retval = 0;
00074   while (std::getline(std::cin, s)) {
00075     try {
00076       std::istringstream str(s);
00077       real lat, lon, h, x, y, z;
00078       std::string stra, strb, strc;
00079       if (!(str >> stra >> strb >> strc))
00080         throw  GeographicErr("Incomplete input: " + s);
00081       if (reverse) {
00082         x = DMS::Decode(stra);
00083         y = DMS::Decode(strb);
00084         z = DMS::Decode(strc);
00085       } else {
00086         DMS::DecodeLatLon(stra, strb, lat, lon);
00087         h = DMS::Decode(strc);
00088       }
00089       std::string strd;
00090       if (str >> strd)
00091         throw GeographicErr("Extraneous input: " + strd);
00092       if (reverse) {
00093         if (localcartesian)
00094           lc.Reverse(x, y, z, lat, lon, h);
00095         else
00096           ec.Reverse(x, y, z, lat, lon, h);
00097         std::cout << DMS::Encode(lat, 15, DMS::NUMBER) << " "
00098                   << DMS::Encode(lon, 15, DMS::NUMBER) << " "
00099                   << DMS::Encode(h, 12, DMS::NUMBER) << "\n";
00100       } else {
00101         if (localcartesian)
00102           lc.Forward(lat, lon, h, x, y, z);
00103         else
00104           ec.Forward(lat, lon, h, x, y, z);
00105         std::cout << DMS::Encode(x, 10, DMS::NUMBER) << " "
00106                   << DMS::Encode(y, 10, DMS::NUMBER) << " "
00107                   << DMS::Encode(z, 10, DMS::NUMBER) << "\n";
00108       }
00109     }
00110     catch (const std::exception& e) {
00111       std::cout << "ERROR: " << e.what() << "\n";
00112       retval = 1;
00113     }
00114   }
00115 
00116   return retval;
00117 }