00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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 }