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/Geodesic.hpp>
00029 #include <GeographicLib/AzimuthalEquidistant.hpp>
00030 #include <GeographicLib/CassiniSoldner.hpp>
00031 #include <GeographicLib/Gnomonic.hpp>
00032 #include <GeographicLib/DMS.hpp>
00033 #include <GeographicLib/Utility.hpp>
00034
00035 #if defined(_MSC_VER)
00036
00037
00038 # pragma warning (disable: 4127 4701)
00039 #endif
00040
00041 #include "GeodesicProj.usage"
00042
00043 int main(int argc, char* argv[]) {
00044 try {
00045 using namespace GeographicLib;
00046 typedef Math::real real;
00047 Utility::set_digits();
00048 bool azimuthal = false, cassini = false, gnomonic = false, reverse = false;
00049 real lat0 = 0, lon0 = 0;
00050 real
00051 a = Constants::WGS84_a(),
00052 f = Constants::WGS84_f();
00053 int prec = 6;
00054 std::string istring, ifile, ofile, cdelim;
00055 char lsep = ';';
00056
00057 for (int m = 1; m < argc; ++m) {
00058 std::string arg(argv[m]);
00059 if (arg == "-r")
00060 reverse = true;
00061 else if (arg == "-c" || arg == "-z" || arg == "-g") {
00062 cassini = arg == "-c";
00063 azimuthal = arg == "-z";
00064 gnomonic = arg == "-g";
00065 if (m + 2 >= argc) return usage(1, true);
00066 try {
00067 DMS::DecodeLatLon(std::string(argv[m + 1]), std::string(argv[m + 2]),
00068 lat0, lon0);
00069 }
00070 catch (const std::exception& e) {
00071 std::cerr << "Error decoding arguments of " << arg << ": "
00072 << e.what() << "\n";
00073 return 1;
00074 }
00075 m += 2;
00076 } else if (arg == "-e") {
00077 if (m + 2 >= argc) return usage(1, true);
00078 try {
00079 a = Utility::num<real>(std::string(argv[m + 1]));
00080 f = Utility::fract<real>(std::string(argv[m + 2]));
00081 }
00082 catch (const std::exception& e) {
00083 std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";
00084 return 1;
00085 }
00086 m += 2;
00087 } else if (arg == "-p") {
00088 if (++m == argc) return usage(1, true);
00089 try {
00090 prec = Utility::num<int>(std::string(argv[m]));
00091 }
00092 catch (const std::exception&) {
00093 std::cerr << "Precision " << argv[m] << " is not a number\n";
00094 return 1;
00095 }
00096 } else if (arg == "--input-string") {
00097 if (++m == argc) return usage(1, true);
00098 istring = argv[m];
00099 } else if (arg == "--input-file") {
00100 if (++m == argc) return usage(1, true);
00101 ifile = argv[m];
00102 } else if (arg == "--output-file") {
00103 if (++m == argc) return usage(1, true);
00104 ofile = argv[m];
00105 } else if (arg == "--line-separator") {
00106 if (++m == argc) return usage(1, true);
00107 if (std::string(argv[m]).size() != 1) {
00108 std::cerr << "Line separator must be a single character\n";
00109 return 1;
00110 }
00111 lsep = argv[m][0];
00112 } else if (arg == "--comment-delimiter") {
00113 if (++m == argc) return usage(1, true);
00114 cdelim = argv[m];
00115 } else if (arg == "--version") {
00116 std::cout
00117 << argv[0] << ": GeographicLib version "
00118 << GEOGRAPHICLIB_VERSION_STRING << "\n";
00119 return 0;
00120 } else
00121 return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00122 }
00123
00124 if (!ifile.empty() && !istring.empty()) {
00125 std::cerr << "Cannot specify --input-string and --input-file together\n";
00126 return 1;
00127 }
00128 if (ifile == "-") ifile.clear();
00129 std::ifstream infile;
00130 std::istringstream instring;
00131 if (!ifile.empty()) {
00132 infile.open(ifile.c_str());
00133 if (!infile.is_open()) {
00134 std::cerr << "Cannot open " << ifile << " for reading\n";
00135 return 1;
00136 }
00137 } else if (!istring.empty()) {
00138 std::string::size_type m = 0;
00139 while (true) {
00140 m = istring.find(lsep, m);
00141 if (m == std::string::npos)
00142 break;
00143 istring[m] = '\n';
00144 }
00145 instring.str(istring);
00146 }
00147 std::istream* input = !ifile.empty() ? &infile :
00148 (!istring.empty() ? &instring : &std::cin);
00149
00150 std::ofstream outfile;
00151 if (ofile == "-") ofile.clear();
00152 if (!ofile.empty()) {
00153 outfile.open(ofile.c_str());
00154 if (!outfile.is_open()) {
00155 std::cerr << "Cannot open " << ofile << " for writing\n";
00156 return 1;
00157 }
00158 }
00159 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;
00160
00161 if (!(azimuthal || cassini || gnomonic)) {
00162 std::cerr << "Must specify \"-z lat0 lon0\" or "
00163 << "\"-c lat0 lon0\" or \"-g lat0 lon0\"\n";
00164 return 1;
00165 }
00166
00167 const Geodesic geod(a, f);
00168 const CassiniSoldner cs = cassini ?
00169 CassiniSoldner(lat0, lon0, geod) : CassiniSoldner(geod);
00170 const AzimuthalEquidistant az(geod);
00171 const Gnomonic gn(geod);
00172
00173
00174
00175 prec = std::min(10 + Math::extra_digits(), std::max(0, prec));
00176 std::string s;
00177 int retval = 0;
00178 std::cout << std::fixed;
00179 while (std::getline(*input, s)) {
00180 try {
00181 std::string eol("\n");
00182 if (!cdelim.empty()) {
00183 std::string::size_type m = s.find(cdelim);
00184 if (m != std::string::npos) {
00185 eol = " " + s.substr(m) + "\n";
00186 s = s.substr(0, m);
00187 }
00188 }
00189 std::istringstream str(s);
00190 real lat, lon, x, y, azi, rk;
00191 std::string stra, strb;
00192 if (!(str >> stra >> strb))
00193 throw GeographicErr("Incomplete input: " + s);
00194 if (reverse) {
00195 x = Utility::num<real>(stra);
00196 y = Utility::num<real>(strb);
00197 } else
00198 DMS::DecodeLatLon(stra, strb, lat, lon);
00199 std::string strc;
00200 if (str >> strc)
00201 throw GeographicErr("Extraneous input: " + strc);
00202 if (reverse) {
00203 if (cassini)
00204 cs.Reverse(x, y, lat, lon, azi, rk);
00205 else if (azimuthal)
00206 az.Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
00207 else
00208 gn.Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
00209 *output << Utility::str(lat, prec + 5) << " "
00210 << Utility::str(lon, prec + 5) << " "
00211 << Utility::str(azi, prec + 5) << " "
00212 << Utility::str(rk, prec + 6) << eol;
00213 } else {
00214 if (cassini)
00215 cs.Forward(lat, lon, x, y, azi, rk);
00216 else if (azimuthal)
00217 az.Forward(lat0, lon0, lat, lon, x, y, azi, rk);
00218 else
00219 gn.Forward(lat0, lon0, lat, lon, x, y, azi, rk);
00220 *output << Utility::str(x, prec) << " "
00221 << Utility::str(y, prec) << " "
00222 << Utility::str(azi, prec + 5) << " "
00223 << Utility::str(rk, prec + 6) << eol;
00224 }
00225 }
00226 catch (const std::exception& e) {
00227 *output << "ERROR: " << e.what() << "\n";
00228 retval = 1;
00229 }
00230 }
00231 return retval;
00232 }
00233 catch (const std::exception& e) {
00234 std::cerr << "Caught exception: " << e.what() << "\n";
00235 return 1;
00236 }
00237 catch (...) {
00238 std::cerr << "Caught unknown exception\n";
00239 return 1;
00240 }
00241 }