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) <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 \ref cartconvert for usage information.
00012  **********************************************************************/
00013 
00014 #include "GeographicLib/Geocentric.hpp"
00015 #include "GeographicLib/LocalCartesian.hpp"
00016 #include "GeographicLib/DMS.hpp"
00017 #include <iostream>
00018 #include <iomanip>
00019 #include <sstream>
00020 
00021 int usage(int retval) {
00022   ( retval ? std::cerr : std::cout ) <<
00023 "Usage: CartConvert [-r] [-l lat0 lon0 h0] [-e a r] [-h]\n\
00024 $Id: CartConvert.cpp 6827 2010-05-20 19:56:18Z karney $\n\
00025 \n\
00026 Convert geodetic coordinates to either geocentric or local cartesian\n\
00027 coordinates.  Geocentric coordinates have the origin at the center of the\n\
00028 earth, with the z axis going thru the north pole, and the x axis thru lat =\n\
00029 0, lon = 0.  By default, the conversion is to geocentric coordinates.\n\
00030 Specifying -l lat0 lon0 h0 causes a local coordinate system to be used with\n\
00031 the origin at latitude = lat0, longitude = lon0, height = h0, z normal to\n\
00032 the ellipsoid and y due north.\n\
00033 \n\
00034 By default, the WGS84 ellipsoid is used.  Specifying \"-e a r\" sets the\n\
00035 equatorial radius of the ellipsoid to \"a\" and the reciprocal flattening\n\
00036 to r.  Setting r = 0 results in a sphere.  Specify r < 0 for a prolate\n\
00037 ellipsoid.\n\
00038 \n\
00039 Geodetic coordinates are provided on standard input as a set of lines\n\
00040 containing (blank separated) latitude, longitude (degrees or DMS), and\n\
00041 height (meters).  For each set of geodetic coordinates, the corresponding\n\
00042 cartesian coordinates x, y, z (meters) are printed on standard output.\n\
00043 \n\
00044 If -r is given the reverse transformation is performed.\n\
00045 \n\
00046 -h prints this help.\n";
00047   return retval;
00048 }
00049 
00050 int main(int argc, char* argv[]) {
00051   using namespace GeographicLib;
00052   typedef Math::real real;
00053   bool localcartesian = false, reverse = false;
00054   real
00055     a = Constants::WGS84_a(),
00056     r = Constants::WGS84_r();
00057   real lat0 = 0, lon0 = 0, h0 = 0;
00058   for (int m = 1; m < argc; ++m) {
00059     std::string arg(argv[m]);
00060     if (arg == "-r")
00061       reverse = true;
00062     else if (arg == "-l") {
00063       localcartesian = true;
00064       if (m + 3 >= argc) return usage(1);
00065       try {
00066         DMS::DecodeLatLon(std::string(argv[m + 1]), std::string(argv[m + 2]),
00067                           lat0, lon0);
00068         h0 = DMS::Decode(std::string(argv[m + 3]));
00069       }
00070       catch (const std::exception& e) {
00071         std::cerr << "Error decoding arguments of -l: " << e.what() << "\n";
00072         return 1;
00073       }
00074       m += 3;
00075     } else if (arg == "-e") {
00076       if (m + 2 >= argc) return usage(1);
00077       try {
00078         a = DMS::Decode(std::string(argv[m + 1]));
00079         r = DMS::Decode(std::string(argv[m + 2]));
00080       }
00081       catch (const std::exception& e) {
00082         std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";
00083         return 1;
00084       }
00085       m += 2;
00086     } else
00087       return usage(arg != "-h");
00088   }
00089 
00090   const Geocentric ec(a, r);
00091   const LocalCartesian lc(lat0, lon0, h0, ec);
00092 
00093   std::string s;
00094   int retval = 0;
00095   std::cout << std::setprecision(16);
00096   while (std::getline(std::cin, s)) {
00097     try {
00098       std::istringstream str(s);
00099       real lat, lon, h, x, y, z;
00100       std::string stra, strb, strc;
00101       if (!(str >> stra >> strb >> strc))
00102         throw  GeographicErr("Incomplete input: " + s);
00103       if (reverse) {
00104         x = DMS::Decode(stra);
00105         y = DMS::Decode(strb);
00106         z = DMS::Decode(strc);
00107       } else {
00108         DMS::DecodeLatLon(stra, strb, lat, lon);
00109         h = DMS::Decode(strc);
00110       }
00111       std::string strd;
00112       if (str >> strd)
00113         throw GeographicErr("Extraneous input: " + strd);
00114       if (reverse) {
00115         if (localcartesian)
00116           lc.Reverse(x, y, z, lat, lon, h);
00117         else
00118           ec.Reverse(x, y, z, lat, lon, h);
00119         std::cout << lat << " " << lon << " " << h << "\n";
00120       } else {
00121         if (localcartesian)
00122           lc.Forward(lat, lon, h, x, y, z);
00123         else
00124           ec.Forward(lat, lon, h, x, y, z);
00125         std::cout << x << " " << y << " " << z << "\n";
00126       }
00127     }
00128     catch (const std::exception& e) {
00129       std::cout << "ERROR: " << e.what() << "\n";
00130       retval = 1;
00131     }
00132   }
00133 
00134   return retval;
00135 }

Generated on 21 May 2010 for GeographicLib by  doxygen 1.6.1