]> git.mxchange.org Git - simgear.git/commitdiff
Fix problems parsing METAR strings that denote temporary sensor failures
authorRichard Senior <richard.j.senior@gmail.com>
Tue, 5 Apr 2016 10:49:59 +0000 (11:49 +0100)
committerRichard Senior <richard.j.senior@gmail.com>
Tue, 5 Apr 2016 11:12:04 +0000 (12:12 +0100)
1. Weather (normally blank, RA, SN, etc.) can be "//"
2. Cloud can be suffixed by "///", e.g. FEW045///

Also updated unit test.

simgear/environment/metar.cxx
simgear/environment/test_metar.cxx

index ec4375ab7e7a0871be877f3e412ba5ed9ceaeb49..4e96839cbd8fefdd4aa7914c69a55c4ff9319e85 100644 (file)
 /**
  * @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>
@@ -465,6 +475,7 @@ bool SGMetar::scanRwyVisRange()
        char *m = _m;
        int i;
        SGMetarRunway r;
+
        if (*m++ != 'R')
                return false;
        if (!scanNumber(&m, &i, 2))
@@ -582,6 +593,14 @@ bool SGMetar::scanWeather()
        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;
@@ -591,7 +610,7 @@ bool SGMetar::scanWeather()
        }
 
        string pre, post;
-    struct Weather w;
+       struct Weather w;
        if (*m == '-')
                m++, pre = "light ", w.intensity = LIGHT;
        else if (*m == '+')
@@ -685,7 +704,7 @@ bool SGMetar::scanSkyCondition()
                        return false;
 
                if (i == 3) {
-            cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
+                       cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
                        _clouds.push_back(cl);
                } else {
                        _cavok = true;
@@ -716,7 +735,7 @@ bool SGMetar::scanSkyCondition()
        } 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///'
@@ -735,9 +754,15 @@ bool SGMetar::scanSkyCondition()
                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;
index 814094b2eea8b66ccc32721d2af7d409791d4f4f..4193418823963078ef7362ae1cb3a6d80c7b782b 100644 (file)
@@ -58,6 +58,37 @@ void test_basic()
     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);
@@ -66,7 +97,9 @@ void test_basic()
 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;