Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <iostream>
00017 #include <sstream>
00018 #include <string>
00019 #include <stdexcept>
00020 #include <iomanip>
00021 #include "GeographicLib/GeoCoords.hpp"
00022
00023 int usage(int retval) {
00024 ( retval ? std::cerr : std::cout ) <<
00025 "Usage: GeoConvert [-g|-d|-u|-m|-c] [-p prec] [-z zone] [-s] [-h]\n\
00026 $Id: GeoConvert.cpp 6559 2009-02-28 16:49:53Z ckarney $\n\
00027 \n\
00028 Convert geographic coordinates to\n\
00029 \n\
00030 -g latitude and longitude (decimal degrees), default output\n\
00031 -d latitude and longitude (degrees mins secs)\n\
00032 -u UTM or UPS\n\
00033 -m MGRS\n\
00034 -c meridian convergence and scale\n\
00035 \n\
00036 The WGS84 model of the earth is used. Geographic coordinates are given on\n\
00037 standard input as:\n\
00038 \n\
00039 Latitude and longitude (decimal degrees or degrees minutes seconds). d,\n\
00040 ', and \" are used to denote degrees, minutes, and seconds, with the least\n\
00041 significant designator optional. Latitude is given first unless a\n\
00042 hemisphere is specified, e.g., the following are all equivalent\n\
00043 \n\
00044 33.3 44.4\n\
00045 E44.4 N33.3\n\
00046 33d18'N 44d24'E\n\
00047 44d24 33d18N\n\
00048 \n\
00049 UTM or UPS given as zone+hemisphere easting northing or easting northing\n\
00050 zone+hemisphere. The zone is absent for a UPS specification. E.g.,\n\
00051 \n\
00052 38N 444140.54 3684706.36\n\
00053 444140.54 3684706.36 38N\n\
00054 S 2173854.98 2985980.58\n\
00055 2173854.98 2985980.58 S\n\
00056 \n\
00057 MRGS is used to specify the center of a grid square, e.g.,\n\
00058 \n\
00059 38SMB4484\n\
00060 38SMB44140847064\n\
00061 \n\
00062 -p prec (default 0) sets the precision relative to 1m. This gives the\n\
00063 number of digits after the decimal point for UTM/UPS. The number of digits\n\
00064 per coordinate for MGRS is 5 + prec. For decimal degrees, the number of\n\
00065 digits after the decimal point is 5 + prec. For DMS (degree, minute,\n\
00066 seconds) output, the number of digits after the decimal point in the\n\
00067 seconds components is 1 + prec; if this is negative then use minutes (prec\n\
00068 = -2 or -3) or degrees (prec <= -4) as the least significant component.\n\
00069 Print convergence, resp. scale, with 5 + prec, resp. 7 + prec, digits after\n\
00070 the decimal point. The minimum value of prec is -5 and the maximum is 9\n\
00071 for UTM/UPS, 9 for decimal degrees, 10 for DMS, 6 for MGRS, and 8 for\n\
00072 convergence and scale.\n\
00073 \n\
00074 MGRS coordinates are given by truncating (instead of rounding) the\n\
00075 coordinates to the requested precision. For example is prec = -3, the\n\
00076 result is the 1km square enclosing the position.\n\
00077 \n\
00078 Convergence is the bearing of grid north given as degrees clockwise from\n\
00079 true north.\n\
00080 \n\
00081 UTM/UPS and MGRS are given in zone of the input if applicable, otherwise in\n\
00082 the standard zone.\n\
00083 \n\
00084 -z zone sets the zone for output. Use zone = 0 to specify UPS.\n\
00085 \n\
00086 -s uses the standard zone.\n\
00087 \n\
00088 For example, the point\n\
00089 \n\
00090 79.9S 6.1E\n\
00091 \n\
00092 corresponds to possible MGRS coordinates\n\
00093 \n\
00094 32CMS4324728161 (standard UTM zone = 32)\n\
00095 31CEM6066227959 (neighboring UTM zone = 31)\n\
00096 BBZ1945517770 (neighboring UPS zone)\n\
00097 \n\
00098 then\n\
00099 echo 79.9S 6.1E | GeoConvert -p -3 -m ==> 32CMS4328\n\
00100 echo 31CEM6066227959 | GeoConvert -p -3 -m ==> 31CEM6027\n\
00101 echo 31CEM6066227959 | GeoConvert -p -3 -m -s ==> 32CMS4328\n\
00102 echo 31CEM6066227959 | GeoConvert -p -3 -m -z 0 ==> BBZ1917\n\
00103 \n\
00104 -h prints this help.\n";
00105 return retval;
00106 }
00107
00108 int main(int argc, char* argv[]) {
00109 enum { GEOGRAPHIC, DMS, UTMUPS, MGRS, CONVERGENCE };
00110 int outputmode = GEOGRAPHIC;
00111 int prec = 0;
00112 int zone = -2;
00113
00114 for (int m = 1; m < argc; ++m) {
00115 std::string arg = std::string(argv[m]);
00116 if (arg == "-g")
00117 outputmode = GEOGRAPHIC;
00118 else if (arg == "-d")
00119 outputmode = DMS;
00120 else if (arg == "-u")
00121 outputmode = UTMUPS;
00122 else if (arg == "-m")
00123 outputmode = MGRS;
00124 else if (arg == "-c")
00125 outputmode = CONVERGENCE;
00126 else if (arg == "-p") {
00127 if (++m == argc) return usage(1);
00128 std::string a = std::string(argv[m]);
00129 std::istringstream str(a);
00130 if (!(str >> prec)) return usage(1);
00131 } else if (arg == "-z") {
00132 if (++m == argc) return usage(1);
00133 std::string a = std::string(argv[m]);
00134 std::istringstream str(a);
00135 if (!(str >> zone)) return usage(1);
00136 } else if (arg == "-s")
00137 zone = -1;
00138 else
00139 return usage(arg != "-h");
00140 }
00141
00142 GeographicLib::GeoCoords p;
00143 std::string s;
00144 std::string os;
00145 int retval = 0;
00146 if (!(zone >= -2 && zone <= 60)) {
00147 std::cerr << "Zone " << zone << "not in [0, 60]\n";
00148 return 1;
00149 }
00150 while (std::getline(std::cin, s)) {
00151 try {
00152 p.Reset(s);
00153 if (zone != -2)
00154 p.SetAltZone(zone);
00155 switch (outputmode) {
00156 case GEOGRAPHIC:
00157 os = p.GeoRepresentation(prec);
00158 break;
00159 case DMS:
00160 os = p.DMSRepresentation(prec);
00161 break;
00162 case UTMUPS:
00163 os = p.AltUTMUPSRepresentation(prec);
00164 break;
00165 case MGRS:
00166 os = p.AltMGRSRepresentation(prec);
00167 break;
00168 case CONVERGENCE:
00169 {
00170 double
00171 gamma = p.AltConvergence(),
00172 k = p.AltScale();
00173 std::ostringstream ss;
00174 ss << std::fixed
00175 << std::setprecision(std::max(-5, std::min(8, prec)) + 5) << gamma
00176 << " "
00177 << std::setprecision(std::max(-5, std::min(8, prec)) + 7) << k;
00178 os = ss.str();
00179 }
00180 }
00181 }
00182 catch (std::out_of_range& e) {
00183
00184 os = std::string("ERROR: ") + e.what();
00185 retval = 1;
00186 }
00187 std::cout << os << std::endl;
00188 }
00189 return retval;
00190 }