/**
* @file metar.cxx
* Interface for encoded Meteorological Aerodrome Reports (METAR).
+ *
+ * @see WMO-49
+ * Technical Regulations, Basic Documents No. 2 (WMO No. 49)
+ * Volume II - Meteorological Service for International Air Navigation
+ * http://library.wmo.int/pmb_ged/wmo_49-v2_2013_en.pdf
+ *
+ * Refer to Table A3-2 (Template for METAR and SPECI) following page 78.
+ *
+ * For general information:
+ * World Meteorological Organization http://library.wmo.int
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
char *m = _m;
int i;
SGMetarRunway r;
+
if (*m++ != 'R')
return false;
if (!scanNumber(&m, &i, 2))
string weather;
const struct Token *a;
+ // @see WMO-49 Section 4.4.2.9
+ // Denotes a temporary failure of the sensor
+ if (!strncmp(m, "// ", 3)) {
+ _m += 3;
+ _grpcount++;
+ return false;
+ }
+
if ((a = scanToken(&m, special))) {
if (!scanBoundary(&m))
return false;
}
string pre, post;
- struct Weather w;
+ struct Weather w;
if (*m == '-')
m++, pre = "light ", w.intensity = LIGHT;
else if (*m == '+')
return false;
if (i == 3) {
- cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
+ cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
_clouds.push_back(cl);
} else {
_cavok = true;
} else if (!scanNumber(&m, &i, 3))
i = -1;
- if (cl._coverage == SGMetarCloud::COVERAGE_NIL) {
+ if (cl._coverage == SGMetarCloud::COVERAGE_NIL) {
if (!scanBoundary(&m))
return false;
if (i == -1) // 'VV///'
cl._type = a->id;
cl._type_long = a->text;
}
+
+ // @see WMO-49 Section 4.5.4.5
+ // Denotes temporary failure of sensor and covers cases like FEW045///
+ if (!strncmp(m, "///", 3))
+ m += 3;
if (!scanBoundary(&m))
return false;
_clouds.push_back(cl);
+
_m = m;
_grpcount++;
return true;
COMPARE(m1.getWindDir(), 270);
FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
+ COMPARE(m1.getWeather().size(), 1);
+ COMPARE(m1.getClouds().size(), 2);
+
+ FUZZY_COMPARE(m1.getTemperature_C(), 10, TEST_EPSILON);
+ FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
+ FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
+}
+
+void test_sensor_failure_weather()
+{
+ SGMetar m1("2011/10/20 11:25 EHAM 201125Z 27012KT 240V300 9999 // FEW025CB SCT048 10/05 Q1025");
+ COMPARE(m1.getWindDir(), 270);
+ FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
+
+ COMPARE(m1.getWeather().size(), 0);
+ COMPARE(m1.getClouds().size(), 2);
+
+ FUZZY_COMPARE(m1.getTemperature_C(), 10, TEST_EPSILON);
+ FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
+ FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
+}
+
+void test_sensor_failure_cloud()
+{
+ SGMetar m1("2011/10/20 11:25 EHAM 201125Z 27012KT 240V300 9999 FEW025CB/// SCT048/// 10/05 Q1025");
+ COMPARE(m1.getWindDir(), 270);
+ FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
+
+ COMPARE(m1.getWeather().size(), 0);
+ COMPARE(m1.getClouds().size(), 2);
+
FUZZY_COMPARE(m1.getTemperature_C(), 10, TEST_EPSILON);
FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
int main(int argc, char* argv[])
{
try {
- test_basic();
+ test_basic();
+ test_sensor_failure_weather();
+ test_sensor_failure_cloud();
} catch (sg_exception& e) {
cerr << "got exception:" << e.getMessage() << endl;
return -1;