bool NOAADownloader::DownloadMETAR(const char *code, METAR &metar, JobRunner &runner) { #ifndef NDEBUG assert(strlen(code) == 4); for (unsigned i = 0; i < 4; i++) assert((code[i] >= 'A' && code[i] <= 'Z') || (code[i] >= '0' && code[i] <= '9')); #endif // Build file url char url[256] = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"; strcat(url, code); strcat(url, ".TXT"); PathName path(url); // Open download session Net::Session session; if (session.Error()) return false; // Request the file char buffer[4096]; Net::DownloadToBufferJob job(session, path, buffer, sizeof(buffer) - 1); if (!runner.Run(job) || job.GetLength() < 0) return false; buffer[job.GetLength()] = 0; /* * Example: * * Duesseldorf, Germany (EDDL) 51-18N 006-46E 41M * Sep 20, 2011 - 03:50 PM EDT / 2011.09.20 1950 UTC * Wind: from the SW (220 degrees) at 10 MPH (9 KT):0 * Visibility: greater than 7 mile(s):0 * Sky conditions: mostly cloudy * Temperature: 60 F (16 C) * Dew Point: 51 F (11 C) * Relative Humidity: 72% * Pressure (altimeter): 30.21 in. Hg (1023 hPa) * ob: EDDL 201950Z 22009KT 9999 FEW035 BKN038 16/11 Q1023 NOSIG * cycle: 20 */ char *p = buffer; // Skip characters until line feed or string end while (*p != '\n' && *p != 0) p++; if (*p == 0) return false; // Skip characters until slash or string end while (*p != '/' && *p != 0) p++; if (*p == 0) return false; p++; if (*p == 0 || !ParseDecodedDateTime(p, metar.last_update)) return false; // Search for line feed followed by "ob:" char *ob = strstr(p, "\nob:"); if (ob == NULL) return false; *ob = 0; ob += 4; while (*ob == ' ' && *ob != 0) ob++; p = ob; // Skip characters until line feed or string end while (*p != '\n' && *p != '\r' && *p != 0) p++; if (*p != 0) *p = 0; metar.content.clear(); AppendToContentString(ob, metar.content); metar.decoded.clear(); AppendToContentString(buffer, metar.decoded); // Trim the content strings TrimRight(metar.content.buffer()); TrimRight(metar.decoded.buffer()); return true; }
bool NOAADownloader::DownloadTAF(const char *code, TAF &taf, JobRunner &runner) { #ifndef NDEBUG assert(strlen(code) == 4); for (unsigned i = 0; i < 4; i++) assert((code[i] >= 'A' && code[i] <= 'Z') || (code[i] >= '0' && code[i] <= '9')); #endif // Build file url char url[256] = "http://weather.noaa.gov/pub/data/forecasts/taf/stations/"; strcat(url, code); strcat(url, ".TXT"); PathName path(url); // Open download session Net::Session session; if (session.Error()) return false; // Request the file char buffer[4096]; Net::DownloadToBufferJob job(session, path, buffer, sizeof(buffer) - 1); if (!runner.Run(job) || job.GetLength() < 0) return false; buffer[job.GetLength()] = 0; /* * Example: * * 2011/07/01 12:27 * TAF EDDL 011100Z 0112/0218 32010KT 9999 SCT040 * TEMPO 0112/0119 4000 SHRA SCT030CB PROB30 * TEMPO 0112/0118 32015G30KT TSRA * BECMG 0118/0121 32005KT PROB30 * TEMPO 0202/0207 BKN012 * BECMG 0210/0213 31010KT */ // Parse date and time of last update const char *p = ParseDateTime(buffer, taf.last_update); if (p == buffer) return false; // Skip characters until line feed or string end while (*p != '\n' && *p != 0) p++; if (*p == 0) return false; // p is now at the first character after the line feed p++; if (*p == 0) return false; // Read rest of the response into the content string taf.content.clear(); AppendToContentString(p, taf.content); // Trim the content string TrimRight(taf.content.buffer()); return true; }
bool NOAADownloader::DownloadMETAR(const char *code, METAR &metar, JobRunner &runner) { #ifndef NDEBUG assert(strlen(code) == 4); for (unsigned i = 0; i < 4; i++) assert(code[i] >= 'A' && code[i] <= 'Z'); #endif // Build file url char url[256] = "ftp://tgftp.nws.noaa.gov/data/observations/metar/stations/"; strcat(url, code); strcat(url, ".TXT"); PathName path(url); // Open download session Net::Session session; if (session.Error()) return false; // Request the file char buffer[4096]; Net::DownloadToBufferJob job(session, path, buffer, sizeof(buffer) - 1); if (!runner.Run(job) || job.GetLength() < 0) return false; buffer[job.GetLength()] = 0; /* * Example: * * 2011/07/01 10:20 * EDDL 011020Z 31004KT 270V340 9999 SCT032TCU SCT050 17/09 Q1022 TEMPO SHRA */ // Parse date and time of last update const char *p = ParseDateTime(buffer, metar.last_update); if (p == buffer) return false; // Skip characters until line feed or string end while (*p != '\n' && *p != 0) p++; if (*p == 0) return false; // p is now at the first character after the line feed p++; if (*p == 0) return false; // Read rest of the response into the content string metar.content.clear(); AppendToContentString(p, metar.content); // Trim the content string TrimRight(metar.content.buffer()); return true; }