00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024 #include <sstream>
00025 #include <string>
00026 #include <sstream>
00027 #include <fstream>
00028 #include <GeographicLib/GeoCoords.hpp>
00029 #include <GeographicLib/DMS.hpp>
00030 #include <GeographicLib/Utility.hpp>
00031
00032 #if defined(_MSC_VER)
00033
00034 # pragma warning (disable: 4127)
00035 #endif
00036
00037 #include "GeoConvert.usage"
00038
00039 int main(int argc, char* argv[]) {
00040 try {
00041 using namespace GeographicLib;
00042 typedef Math::real real;
00043 Utility::set_digits();
00044 enum { GEOGRAPHIC, DMS, UTMUPS, MGRS, CONVERGENCE };
00045 int outputmode = GEOGRAPHIC;
00046 int prec = 0;
00047 int zone = UTMUPS::MATCH;
00048 bool centerp = true, swaplatlong = false;
00049 std::string istring, ifile, ofile, cdelim;
00050 char lsep = ';', dmssep = char(0);
00051 bool sethemisphere = false, northp = false, abbrev = true;
00052
00053 for (int m = 1; m < argc; ++m) {
00054 std::string arg(argv[m]);
00055 if (arg == "-g")
00056 outputmode = GEOGRAPHIC;
00057 else if (arg == "-d") {
00058 outputmode = DMS;
00059 dmssep = '\0';
00060 } else if (arg == "-:") {
00061 outputmode = DMS;
00062 dmssep = ':';
00063 } else if (arg == "-u")
00064 outputmode = UTMUPS;
00065 else if (arg == "-m")
00066 outputmode = MGRS;
00067 else if (arg == "-c")
00068 outputmode = CONVERGENCE;
00069 else if (arg == "-n")
00070 centerp = false;
00071 else if (arg == "-w")
00072 swaplatlong = true;
00073 else if (arg == "-l")
00074 abbrev = false;
00075 else if (arg == "-a")
00076 abbrev = true;
00077 else if (arg == "-p") {
00078 if (++m == argc) return usage(1, true);
00079 try {
00080 prec = Utility::num<int>(std::string(argv[m]));
00081 }
00082 catch (const std::exception&) {
00083 std::cerr << "Precision " << argv[m] << " is not a number\n";
00084 return 1;
00085 }
00086 } else if (arg == "-z") {
00087 if (++m == argc) return usage(1, true);
00088 std::string zonestr(argv[m]);
00089 try {
00090 UTMUPS::DecodeZone(zonestr, zone, northp);
00091 sethemisphere = true;
00092 }
00093 catch (const std::exception&) {
00094 std::istringstream str(zonestr);
00095 char c;
00096 if (!(str >> zone) || (str >> c)) {
00097 std::cerr << "Zone " << zonestr
00098 << " is not a number or zone+hemisphere\n";
00099 return 1;
00100 }
00101 if (!(zone >= UTMUPS::MINZONE && zone <= UTMUPS::MAXZONE)) {
00102 std::cerr << "Zone " << zone << " not in [0, 60]\n";
00103 return 1;
00104 }
00105 sethemisphere = false;
00106 }
00107 } else if (arg == "-s") {
00108 zone = UTMUPS::STANDARD;
00109 sethemisphere = false;
00110 } else if (arg == "-t") {
00111 zone = UTMUPS::UTM;
00112 sethemisphere = false;
00113 } else if (arg == "--input-string") {
00114 if (++m == argc) return usage(1, true);
00115 istring = argv[m];
00116 } else if (arg == "--input-file") {
00117 if (++m == argc) return usage(1, true);
00118 ifile = argv[m];
00119 } else if (arg == "--output-file") {
00120 if (++m == argc) return usage(1, true);
00121 ofile = argv[m];
00122 } else if (arg == "--line-separator") {
00123 if (++m == argc) return usage(1, true);
00124 if (std::string(argv[m]).size() != 1) {
00125 std::cerr << "Line separator must be a single character\n";
00126 return 1;
00127 }
00128 lsep = argv[m][0];
00129 } else if (arg == "--comment-delimiter") {
00130 if (++m == argc) return usage(1, true);
00131 cdelim = argv[m];
00132 } else if (arg == "--version") {
00133 std::cout
00134 << argv[0] << ": GeographicLib version "
00135 << GEOGRAPHICLIB_VERSION_STRING << "\n";
00136 return 0;
00137 } else
00138 return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00139 }
00140
00141 if (!ifile.empty() && !istring.empty()) {
00142 std::cerr << "Cannot specify --input-string and --input-file together\n";
00143 return 1;
00144 }
00145 if (ifile == "-") ifile.clear();
00146 std::ifstream infile;
00147 std::istringstream instring;
00148 if (!ifile.empty()) {
00149 infile.open(ifile.c_str());
00150 if (!infile.is_open()) {
00151 std::cerr << "Cannot open " << ifile << " for reading\n";
00152 return 1;
00153 }
00154 } else if (!istring.empty()) {
00155 std::string::size_type m = 0;
00156 while (true) {
00157 m = istring.find(lsep, m);
00158 if (m == std::string::npos)
00159 break;
00160 istring[m] = '\n';
00161 }
00162 instring.str(istring);
00163 }
00164 std::istream* input = !ifile.empty() ? &infile :
00165 (!istring.empty() ? &instring : &std::cin);
00166
00167 std::ofstream outfile;
00168 if (ofile == "-") ofile.clear();
00169 if (!ofile.empty()) {
00170 outfile.open(ofile.c_str());
00171 if (!outfile.is_open()) {
00172 std::cerr << "Cannot open " << ofile << " for writing\n";
00173 return 1;
00174 }
00175 }
00176 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;
00177
00178 GeoCoords p;
00179 std::string s;
00180 std::string os;
00181 int retval = 0;
00182
00183 while (std::getline(*input, s)) {
00184 std::string eol("\n");
00185 try {
00186 if (!cdelim.empty()) {
00187 std::string::size_type m = s.find(cdelim);
00188 if (m != std::string::npos) {
00189 eol = " " + s.substr(m) + "\n";
00190 s = s.substr(0, m);
00191 }
00192 }
00193 p.Reset(s, centerp, swaplatlong);
00194 p.SetAltZone(zone);
00195 switch (outputmode) {
00196 case GEOGRAPHIC:
00197 os = p.GeoRepresentation(prec, swaplatlong);
00198 break;
00199 case DMS:
00200 os = p.DMSRepresentation(prec, swaplatlong, dmssep);
00201 break;
00202 case UTMUPS:
00203 os = (sethemisphere
00204 ? p.AltUTMUPSRepresentation(northp, prec, abbrev)
00205 : p.AltUTMUPSRepresentation(prec, abbrev));
00206 break;
00207 case MGRS:
00208 os = p.AltMGRSRepresentation(prec);
00209 break;
00210 case CONVERGENCE:
00211 {
00212 real
00213 gamma = p.AltConvergence(),
00214 k = p.AltScale();
00215 int prec1 = std::max(-5, std::min(Math::extra_digits() + 8, prec));
00216 os = Utility::str(gamma, prec1 + 5) + " "
00217 + Utility::str(k, prec1 + 7);
00218 }
00219 }
00220 }
00221 catch (const std::exception& e) {
00222
00223 os = std::string("ERROR: ") + e.what();
00224 retval = 1;
00225 }
00226 *output << os << eol;
00227 }
00228 return retval;
00229 }
00230 catch (const std::exception& e) {
00231 std::cerr << "Caught exception: " << e.what() << "\n";
00232 return 1;
00233 }
00234 catch (...) {
00235 std::cerr << "Caught unknown exception\n";
00236 return 1;
00237 }
00238 }