X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Fmetar_main.cxx;h=977ebf4c1f6f05889d2b59b4548d81363e2e3a6e;hb=43fcbd22463b32d95678edf920d7184055b2d63e;hp=20b638591602393bd8e3decb1a9fffa18dc0b501;hpb=f2199a4f57b49a37b4a8bbb843bc08dc8d7849c4;p=flightgear.git diff --git a/src/Main/metar_main.cxx b/src/Main/metar_main.cxx index 20b638591..977ebf4c1 100644 --- a/src/Main/metar_main.cxx +++ b/src/Main/metar_main.cxx @@ -16,21 +16,33 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ #include #include +#include +#include +#include +#include +#include + +#include -#include -#include #include +#include + +#include +#include +#include +#include using namespace std; +using namespace simgear; // text color -#if defined(__linux__) || defined( __sun__ ) ||defined(__CYGWIN__) || defined( __FreeBSD__ ) +#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) || defined( __FreeBSD__ ) || defined ( sgi ) # define R "\033[31;1m" // red # define G "\033[32;1m" // green # define Y "\033[33;1m" // yellow @@ -73,11 +85,11 @@ const char *azimuthName(double d) double rnd(double r, int g = 0) { double f = pow(10.0, g); - return f * rint(r / f); + return f * floor(r / f + 0.5); } -ostream& operator<<(ostream& s, SGMetarVisibility& v) +ostream& operator<<(ostream& s, const SGMetarVisibility& v) { ostringstream buf; int m = v.getModifier(); @@ -132,9 +144,7 @@ void printReport(SGMetar *m) // date/time int year = m->getYear(); int month = m->getMonth(); - cout << "Report time:\t\t"; - if (year != -1 && month != -1) - cout << year << '/' << month << '/' << m->getDay(); + cout << "Report time:\t\t" << year << '/' << month << '/' << m->getDay(); cout << ' ' << m->getHour() << ':'; cout << setw(2) << setfill('0') << m->getMinute() << " UTC" << endl; @@ -154,7 +164,7 @@ void printReport(SGMetar *m) // directed visibility - SGMetarVisibility *dirvis = m->getDirVisibility(); + const SGMetarVisibility *dirvis = m->getDirVisibility(); for (i = 0; i < 8; i++, dirvis++) if (dirvis->getVisibility_m() != NaN) cout << "\t\t\t" << *dirvis << endl; @@ -177,7 +187,7 @@ void printReport(SGMetar *m) if ((i = m->getWindDir()) == -1) cout << "from variable directions"; else - cout << "from the " << azimuthName(i) << " (" << i << "°)"; + cout << "from the " << azimuthName(i) << " (" << i << "°)"; cout << " at " << rnd(d, -1) << " km/h"; cout << "\t\t" << rnd(m->getWindSpeed_kt(), -1) << " kt"; @@ -198,19 +208,19 @@ void printReport(SGMetar *m) if (from != to) { cout << "\t\t\tvariable from " << azimuthName(from); cout << " to " << azimuthName(to); - cout << " (" << from << "°--" << to << "°)" << endl; + cout << " (" << from << "°--" << to << "°)" << endl; } } // temperature/humidity/air pressure if ((d = m->getTemperature_C()) != NaN) { - cout << "Temperature:\t\t" << d << "°C\t\t\t\t\t"; - cout << rnd(m->getTemperature_F(), -1) << "°F" << endl; + cout << "Temperature:\t\t" << d << "°C\t\t\t\t\t"; + cout << rnd(m->getTemperature_F(), -1) << "°F" << endl; if ((d = m->getDewpoint_C()) != NaN) { - cout << "Dewpoint:\t\t" << d << "°C\t\t\t\t\t"; - cout << rnd(m->getDewpoint_F(), -1) << "°F" << endl; + cout << "Dewpoint:\t\t" << d << "°C\t\t\t\t\t"; + cout << rnd(m->getDewpoint_F(), -1) << "°F" << endl; cout << "Rel. Humidity:\t\t" << rnd(m->getRelHumidity()) << "%" << endl; } } @@ -264,12 +274,12 @@ void printReport(SGMetar *m) // assemble surface string vector surface; - if ((s = rwy.getDeposit()) && strlen(s)) + if ((s = rwy.getDepositString()) && strlen(s)) surface.push_back(s); if ((s = rwy.getExtentString()) && strlen(s)) surface.push_back(s); if ((d = rwy.getDepth()) != NaN) { - sprintf(buf, "%.0lf mm", d * 1000.0); + sprintf(buf, "%.1lf mm", d * 1000.0); surface.push_back(buf); } if ((s = rwy.getFrictionString()) && strlen(s)) @@ -279,7 +289,7 @@ void printReport(SGMetar *m) surface.push_back(buf); } - if (surface.size()) { + if (! surface.empty()) { vector::iterator rwysurf = surface.begin(); for (i = 0; rwysurf != surface.end(); rwysurf++, i++) { if (i) @@ -413,7 +423,7 @@ void printArgs(SGMetar *m, double airport_elevation) sprintf(&buf[strlen(buf)], ":%.0lf", gust_speed); args.push_back(buf); } - + // output everything //cout << "fgfs" << endl; @@ -426,26 +436,64 @@ void printArgs(SGMetar *m, double airport_elevation) } -void help() +void getproxy(string& host, string& port) +{ + host = ""; + port = "80"; + + const char *p = getenv("http_proxy"); + if (!p) + return; + while (isspace(*p)) + p++; + if (!strncmp(p, "http://", 7)) + p += 7; + if (!*p) + return; + + char s[256], *t; + strncpy(s, p, 255); + s[255] = '\0'; + + for (t = s + strlen(s); t > s; t--) + if (!isspace(t[-1]) && t[-1] != '/') + break; + *t = '\0'; + + t = strchr(s, ':'); + if (t) { + *t++ = '\0'; + port = t; + } + host = s; +} + + +void usage() { printf( - "Usage: metar [-v] [-e elevation] [-r|-c] \n" - " -h|--help show this help\n" - " -v|--verbose verbose output\n" - " -r|--report print report (default)\n" - " -c|--command-line print command line\n" - " -e E|--elevation E set airport elevation to E meters\n" - " (added to cloud bases in command line mode)\n" + "Usage: metar [-v] [-e elevation] [-r|-c] \n" + " metar -h\n" + "\n" + " -h|--help show this help\n" + " -v|--verbose verbose output\n" + " -r|--report print report (default)\n" + " -c|--command-line print command line\n" + " -e E|--elevation E set airport elevation to E meters\n" + " (added to cloud bases in command line mode)\n" + "Environment:\n" + " http_proxy set proxy in the form \"http://host:port/\"\n" "\n" - "Examples: metar ksfo koak\n" - " metar -c ksfo -r ksfo\n" - " metar \"LOWL 161500Z 19004KT 160V240 9999 FEW035 SCT300 29/23 Q1006 NOSIG\"\n" - " fgfs `metar -e 183 -c loww`\n" + "Examples:\n" + " $ metar ksfo koak\n" + " $ metar -c ksfo -r ksfo\n" + " $ metar \"LOWL 161500Z 19004KT 160V240 9999 FEW035 SCT300 29/23 Q1006 NOSIG\"\n" + " $ fgfs `metar -e 183 -c loww`\n" + " $ http_proxy=http://localhost:3128/ metar ksfo\n" "\n" ); } - int main(int argc, char *argv[]) { bool report = true; @@ -453,13 +501,21 @@ int main(int argc, char *argv[]) double elevation = 0.0; if (argc <= 1) { - help(); + usage(); return 0; } + string proxy_host, proxy_port; + getproxy(proxy_host, proxy_port); + + Socket::initSockets(); + + HTTP::Client http; + http.setProxy(proxy_host, atoi(proxy_port.c_str())); + for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) - help(); + usage(); else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) verbose = true; else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--report")) @@ -468,21 +524,61 @@ int main(int argc, char *argv[]) report = false; else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--elevation")) { if (++i >= argc) { - cerr << "-e options used without elevation" << endl; + cerr << "-e option used without elevation" << endl; return 1; } elevation = strtod(argv[i], 0); } else { - try { - SGMetar *m = new SGMetar(argv[i]); + static bool shown = false; + if (verbose && !shown) { + cerr << "Proxy host: '" << proxy_host << "'" << endl; + cerr << "Proxy port: '" << proxy_port << "'" << endl << endl; + shown = true; + } + + try + { + static const std::string NOAA_BASE_URL = + "http://weather.noaa.gov/pub/data/observations/metar/stations/"; + HTTP::MemoryRequest* mr = new HTTP::MemoryRequest + ( + NOAA_BASE_URL + + boost::to_upper_copy(argv[i]) + ".TXT" + ); + HTTP::Request_ptr own(mr); + http.makeRequest(mr); + + // spin until the request completes, fails or times out + SGTimeStamp start(SGTimeStamp::now()); + while (start.elapsedMSec() < 8000) { + http.update(); + if( mr->isComplete() ) + break; + SGTimeStamp::sleepForMSec(1); + } + + if( !mr->isComplete() ) + throw sg_io_exception("metar download timed out"); + if( mr->responseCode() != 200 ) + { + std::cerr << "metar download failed: " + << mr->url() + << " (" << mr->responseCode() + << " " << mr->responseReason() << ")" + << std::endl; + throw sg_io_exception("metar download failed"); + } + + SGMetar *m = new SGMetar(mr->responseBody()); + //SGMetar *m = new SGMetar("2004/01/11 01:20\nLOWG 110120Z AUTO VRB01KT 0050 1600N R35/0600 FG M06/M06 Q1019 88//////\n"); if (verbose) { - cerr << G"INPUT: " << m->getData() << ""N << endl; + cerr << G "INPUT: " << m->getData() << "" N << endl; const char *unused = m->getUnusedData(); if (*unused) - cerr << R"UNUSED: " << unused << ""N << endl; + cerr << R "UNUSED: " << unused << "" N << endl; } if (report) @@ -492,7 +588,7 @@ int main(int argc, char *argv[]) delete m; } catch (const sg_io_exception& e) { - cerr << R"ERROR: " << e.getFormattedMessage().c_str() << ""N << endl << endl; + cerr << R "ERROR: " << e.getFormattedMessage().c_str() << "" N << endl << endl; } } }