Fix problems parsing METAR strings that denote temporary sensor failures
1. Weather (normally blank, RA, SN, etc.) can be "//" 2. Cloud can be suffixed by "///", e.g. FEW045/// Also updated unit test.
This commit is contained in:
parent
177c5ec709
commit
92a51059b4
@ -23,6 +23,16 @@
|
|||||||
/**
|
/**
|
||||||
* @file metar.cxx
|
* @file metar.cxx
|
||||||
* Interface for encoded Meteorological Aerodrome Reports (METAR).
|
* 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
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <simgear_config.h>
|
# include <simgear_config.h>
|
||||||
@ -465,6 +475,7 @@ bool SGMetar::scanRwyVisRange()
|
|||||||
char *m = _m;
|
char *m = _m;
|
||||||
int i;
|
int i;
|
||||||
SGMetarRunway r;
|
SGMetarRunway r;
|
||||||
|
|
||||||
if (*m++ != 'R')
|
if (*m++ != 'R')
|
||||||
return false;
|
return false;
|
||||||
if (!scanNumber(&m, &i, 2))
|
if (!scanNumber(&m, &i, 2))
|
||||||
@ -582,6 +593,14 @@ bool SGMetar::scanWeather()
|
|||||||
string weather;
|
string weather;
|
||||||
const struct Token *a;
|
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 ((a = scanToken(&m, special))) {
|
||||||
if (!scanBoundary(&m))
|
if (!scanBoundary(&m))
|
||||||
return false;
|
return false;
|
||||||
@ -591,7 +610,7 @@ bool SGMetar::scanWeather()
|
|||||||
}
|
}
|
||||||
|
|
||||||
string pre, post;
|
string pre, post;
|
||||||
struct Weather w;
|
struct Weather w;
|
||||||
if (*m == '-')
|
if (*m == '-')
|
||||||
m++, pre = "light ", w.intensity = LIGHT;
|
m++, pre = "light ", w.intensity = LIGHT;
|
||||||
else if (*m == '+')
|
else if (*m == '+')
|
||||||
@ -685,7 +704,7 @@ bool SGMetar::scanSkyCondition()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
|
cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
|
||||||
_clouds.push_back(cl);
|
_clouds.push_back(cl);
|
||||||
} else {
|
} else {
|
||||||
_cavok = true;
|
_cavok = true;
|
||||||
@ -716,7 +735,7 @@ bool SGMetar::scanSkyCondition()
|
|||||||
} else if (!scanNumber(&m, &i, 3))
|
} else if (!scanNumber(&m, &i, 3))
|
||||||
i = -1;
|
i = -1;
|
||||||
|
|
||||||
if (cl._coverage == SGMetarCloud::COVERAGE_NIL) {
|
if (cl._coverage == SGMetarCloud::COVERAGE_NIL) {
|
||||||
if (!scanBoundary(&m))
|
if (!scanBoundary(&m))
|
||||||
return false;
|
return false;
|
||||||
if (i == -1) // 'VV///'
|
if (i == -1) // 'VV///'
|
||||||
@ -735,9 +754,15 @@ bool SGMetar::scanSkyCondition()
|
|||||||
cl._type = a->id;
|
cl._type = a->id;
|
||||||
cl._type_long = a->text;
|
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))
|
if (!scanBoundary(&m))
|
||||||
return false;
|
return false;
|
||||||
_clouds.push_back(cl);
|
_clouds.push_back(cl);
|
||||||
|
|
||||||
_m = m;
|
_m = m;
|
||||||
_grpcount++;
|
_grpcount++;
|
||||||
return true;
|
return true;
|
||||||
|
@ -58,6 +58,37 @@ void test_basic()
|
|||||||
COMPARE(m1.getWindDir(), 270);
|
COMPARE(m1.getWindDir(), 270);
|
||||||
FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
|
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.getTemperature_C(), 10, TEST_EPSILON);
|
||||||
FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
|
FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
|
||||||
FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
|
FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
|
||||||
@ -66,7 +97,9 @@ void test_basic()
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
test_basic();
|
test_basic();
|
||||||
|
test_sensor_failure_weather();
|
||||||
|
test_sensor_failure_cloud();
|
||||||
} catch (sg_exception& e) {
|
} catch (sg_exception& e) {
|
||||||
cerr << "got exception:" << e.getMessage() << endl;
|
cerr << "got exception:" << e.getMessage() << endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user