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