00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "GeographicLib/Geodesic.hpp"
00016 #include "GeographicLib/GeodesicLine.hpp"
00017 #include "GeographicLib/DMS.hpp"
00018 #include <iostream>
00019 #include <sstream>
00020
00021 #include "Geod.usage"
00022
00023 typedef GeographicLib::Math::real real;
00024
00025 std::string LatLonString(real lat, real lon, int prec, bool dms) {
00026 using namespace GeographicLib;
00027 return dms ?
00028 DMS::Encode(lat, prec + 5, DMS::LATITUDE) + " " +
00029 DMS::Encode(lon, prec + 5, DMS::LONGITUDE) :
00030 DMS::Encode(lat, prec + 5, DMS::NUMBER) + " " +
00031 DMS::Encode(lon, prec + 5, DMS::NUMBER);
00032 }
00033
00034 std::string AzimuthString(real azi, int prec, bool dms) {
00035 using namespace GeographicLib;
00036 return dms ? DMS::Encode(azi, prec + 5, DMS::AZIMUTH) :
00037 DMS::Encode(azi >= 180 ? azi - 360 : azi, prec + 5, DMS::NUMBER);
00038 }
00039
00040 std::string DistanceStrings(real s12, real a12,
00041 bool full, bool arcmode, int prec, bool dms) {
00042 using namespace GeographicLib;
00043 std::string s;
00044 if (full || !arcmode)
00045 s += DMS::Encode(s12, prec, DMS::NUMBER);
00046 if (full)
00047 s += " ";
00048 if (full || arcmode)
00049 s += dms ? DMS::Encode(a12, prec + 5, DMS::NONE) :
00050 DMS::Encode(a12, prec + 5, DMS::NUMBER);
00051 return s;
00052 }
00053
00054 real ReadDistance(const std::string& s, bool arcmode) {
00055 using namespace GeographicLib;
00056 return arcmode ? DMS::DecodeAngle(s) : DMS::Decode(s);
00057 }
00058
00059 int main(int argc, char* argv[]) {
00060 using namespace GeographicLib;
00061 bool linecalc = false, inverse = false, arcmode = false,
00062 dms = false, full = false;
00063 real
00064 a = Constants::WGS84_a<real>(),
00065 r = Constants::WGS84_r<real>();
00066 real lat1, lon1, azi1, lat2, lon2, azi2, s12, m12, a12;
00067 real azi2sense = 0;
00068 int prec = 3;
00069
00070 for (int m = 1; m < argc; ++m) {
00071 std::string arg(argv[m]);
00072 if (arg == "-i") {
00073 inverse = true;
00074 linecalc = false;
00075 } else if (arg == "-a")
00076 arcmode = true;
00077 else if (arg == "-l") {
00078 inverse = false;
00079 linecalc = true;
00080 if (m + 3 >= argc) return usage(1, true);
00081 try {
00082 DMS::DecodeLatLon(std::string(argv[m + 1]), std::string(argv[m + 2]),
00083 lat1, lon1);
00084 azi1 = DMS::DecodeAzimuth(std::string(argv[m + 3]));
00085 }
00086 catch (const std::exception& e) {
00087 std::cerr << "Error decoding arguments of -l: " << e.what() << "\n";
00088 return 1;
00089 }
00090 m += 3;
00091 } else if (arg == "-n") {
00092 a = 6378388;
00093 r = 297;
00094 } else if (arg == "-e") {
00095 if (m + 2 >= argc) return usage(1, true);
00096 try {
00097 a = DMS::Decode(std::string(argv[m + 1]));
00098 r = DMS::Decode(std::string(argv[m + 2]));
00099 }
00100 catch (const std::exception& e) {
00101 std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";
00102 return 1;
00103 }
00104 m += 2;
00105 }
00106 else if (arg == "-d")
00107 dms = true;
00108 else if (arg == "-b")
00109 azi2sense = 180;
00110 else if (arg == "-f")
00111 full = true;
00112 else if (arg == "-p") {
00113 if (++m == argc) return usage(1, true);
00114 std::istringstream str(argv[m]);
00115 char c;
00116 if (!(str >> prec) || (str >> c)) {
00117 std::cerr << "Precision " << argv[m] << " is not a number\n";
00118 return 1;
00119 }
00120 } else if (arg == "--version") {
00121 std::cout
00122 << PROGRAM_NAME
00123 << ": $Id: Geod.cpp 6978 2011-02-21 22:42:11Z karney $\n"
00124 << "GeographicLib version " << GEOGRAPHICLIB_VERSION << "\n";
00125 return 0;
00126 } else
00127 return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00128 }
00129
00130 const Geodesic geod(a, r);
00131 GeodesicLine l;
00132 if (linecalc)
00133 l = geod.Line(lat1, lon1, azi1);
00134
00135
00136
00137 prec = std::min(10, std::max(0, prec));
00138 std::string s;
00139 int retval = 0;
00140 while (std::getline(std::cin, s)) {
00141 try {
00142 std::istringstream str(s);
00143 if (inverse) {
00144 std::string slat1, slon1, slat2, slon2;
00145 if (!(str >> slat1 >> slon1 >> slat2 >> slon2))
00146 throw GeographicErr("Incomplete input: " + s);
00147 std::string strc;
00148 if (str >> strc)
00149 throw GeographicErr("Extraneous input: " + strc);
00150 DMS::DecodeLatLon(slat1, slon1, lat1, lon1);
00151 DMS::DecodeLatLon(slat2, slon2, lat2, lon2);
00152 a12 = geod.Inverse(lat1, lon1, lat2, lon2, s12, azi1, azi2, m12);
00153 if (full)
00154 std::cout << LatLonString(lat1, lon1, prec, dms) << " ";
00155 std::cout << AzimuthString(azi1, prec, dms) << " ";
00156 if (full)
00157 std::cout << LatLonString(lat2, lon2, prec, dms) << " ";
00158 std::cout << AzimuthString(azi2 + azi2sense, prec, dms) << " "
00159 << DistanceStrings(s12, a12, full, arcmode, prec, dms) << " "
00160 << DMS::Encode(m12, prec, DMS::NUMBER) << "\n";
00161 } else {
00162 if (linecalc) {
00163 std::string ss12;
00164 if (!(str >> ss12))
00165 throw GeographicErr("Incomplete input: " + s);
00166 std::string strc;
00167 if (str >> strc)
00168 throw GeographicErr("Extraneous input: " + strc);
00169 s12 = ReadDistance(ss12, arcmode);
00170 if (arcmode)
00171 l.ArcPosition(s12, lat2, lon2, azi2, a12, m12);
00172 else
00173 a12 = l.Position(s12, lat2, lon2, azi2, m12);
00174 } else {
00175 std::string slat1, slon1, sazi1, ss12;
00176 if (!(str >> slat1 >> slon1 >> sazi1 >> ss12))
00177 throw GeographicErr("Incomplete input: " + s);
00178 std::string strc;
00179 if (str >> strc)
00180 throw GeographicErr("Extraneous input: " + strc);
00181 DMS::DecodeLatLon(slat1, slon1, lat1, lon1);
00182 azi1 = DMS::DecodeAzimuth(sazi1);
00183 s12 = ReadDistance(ss12, arcmode);
00184 if (arcmode)
00185 geod.ArcDirect(lat1, lon1, azi1, s12, lat2, lon2, azi2, a12, m12);
00186 else
00187 a12 = geod.Direct(lat1, lon1, azi1, s12, lat2, lon2, azi2, m12);
00188 }
00189 if (arcmode)
00190 std::swap(s12, a12);
00191 if (full)
00192 std::cout << LatLonString(lat1, lon1, prec, dms) << " "
00193 << AzimuthString(azi1, prec, dms) << " ";
00194 std::cout << LatLonString(lat2, lon2, prec, dms) << " "
00195 << AzimuthString(azi2 + azi2sense, prec, dms);
00196 if (full)
00197 std::cout << " "
00198 << DistanceStrings(s12, a12, full, arcmode, prec, dms);
00199 std::cout << " " << DMS::Encode(m12, prec, DMS::NUMBER) << "\n";
00200 }
00201 }
00202 catch (const std::exception& e) {
00203
00204 std::cout << "ERROR: " << e.what() << "\n";
00205 retval = 1;
00206 }
00207 }
00208 return retval;
00209 }