mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:30:05 +00:00
Robust coded location error handling
This commit is contained in:
parent
7d503ec506
commit
8f3baaa7c3
4 changed files with 131 additions and 13 deletions
|
|
@ -228,5 +228,29 @@ TEST(CodedLocation, MalformedData)
|
||||||
EXPECT_EQ(dataValid, false);
|
EXPECT_EQ(dataValid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CodedLocation, InvalidWFOToken)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data = {
|
||||||
|
"LAT...LON abcd 14509 1371 18195 1348 14463 1325 14492"};
|
||||||
|
|
||||||
|
CodedLocation location;
|
||||||
|
bool dataValid = location.Parse(data);
|
||||||
|
|
||||||
|
EXPECT_EQ(dataValid, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CodedLocation, InvalidNCToken)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data = {
|
||||||
|
"LAT...LON 4731abcd 47216795 46466767 45436766 44756779",
|
||||||
|
" 44216834 43816943 43706970 43837006 44497009",
|
||||||
|
" 45306974 46356946 46976921"};
|
||||||
|
|
||||||
|
CodedLocation location;
|
||||||
|
bool dataValid = location.Parse(data);
|
||||||
|
|
||||||
|
EXPECT_EQ(dataValid, false);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace awips
|
} // namespace awips
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
|
|
@ -106,5 +106,38 @@ TEST(CodedTimeMotionLocation, MalformedData)
|
||||||
EXPECT_EQ(dataValid, false);
|
EXPECT_EQ(dataValid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CodedTimeMotionLocation, InvalidDirection)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data = {
|
||||||
|
"TIME...MOT...LOC 1959Z ZZZDEG 0KT 3253 11464"};
|
||||||
|
|
||||||
|
CodedTimeMotionLocation tml;
|
||||||
|
bool dataValid = tml.Parse(data);
|
||||||
|
|
||||||
|
EXPECT_EQ(dataValid, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CodedTimeMotionLocation, InvalidSpeed)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data = {
|
||||||
|
"TIME...MOT...LOC 1959Z 254DEG ZKT 3253 11464"};
|
||||||
|
|
||||||
|
CodedTimeMotionLocation tml;
|
||||||
|
bool dataValid = tml.Parse(data);
|
||||||
|
|
||||||
|
EXPECT_EQ(dataValid, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CodedTimeMotionLocation, InvalidLocation)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data = {
|
||||||
|
"TIME...MOT...LOC 1959Z 254DEG 0KT ZZZZ 11464"};
|
||||||
|
|
||||||
|
CodedTimeMotionLocation tml;
|
||||||
|
bool dataValid = tml.Parse(data);
|
||||||
|
|
||||||
|
EXPECT_EQ(dataValid, false);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace awips
|
} // namespace awips
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,23 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo)
|
||||||
for (auto token = tokenList.cbegin() + 1; token != tokenList.cend();
|
for (auto token = tokenList.cbegin() + 1; token != tokenList.cend();
|
||||||
++token)
|
++token)
|
||||||
{
|
{
|
||||||
double latitude = std::stod(*token) * 0.01;
|
double latitude = 0.0;
|
||||||
|
double longitude = 0.0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
latitude = std::stod(*token) * 0.01;
|
||||||
++token;
|
++token;
|
||||||
double longitude = std::stod(*token) * 0.01;
|
longitude = std::stod(*token) * 0.01;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid WFO location token: \"" << *token
|
||||||
|
<< "\" (" << ex.what() << ")";
|
||||||
|
dataValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// If a given product straddles 180 degrees longitude, those points
|
// If a given product straddles 180 degrees longitude, those points
|
||||||
// west of 180 degrees will be given as if they were west longitude
|
// west of 180 degrees will be given as if they were west longitude
|
||||||
|
|
@ -99,7 +113,7 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo)
|
||||||
p->coordinates_.push_back({latitude, longitude});
|
p->coordinates_.push_back({latitude, longitude});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wfoIsWest && straddlesDateLine)
|
if (dataValid && !wfoIsWest && straddlesDateLine)
|
||||||
{
|
{
|
||||||
for (auto& coordinate : p->coordinates_)
|
for (auto& coordinate : p->coordinates_)
|
||||||
{
|
{
|
||||||
|
|
@ -123,8 +137,22 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double latitude = std::stod(token->substr(0, 4)) * 0.01;
|
double latitude = 0.0;
|
||||||
double longitude = std::stod(token->substr(4, 4)) * -0.01;
|
double longitude = 0.0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
latitude = std::stod(token->substr(0, 4)) * 0.01;
|
||||||
|
longitude = std::stod(token->substr(4, 4)) * -0.01;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid National Center location token: \""
|
||||||
|
<< *token << "\" (" << ex.what() << ")";
|
||||||
|
dataValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Longitudes of greater than 100 degrees will drop the leading 1;
|
// Longitudes of greater than 100 degrees will drop the leading 1;
|
||||||
// i.e., 105.22 W would be coded as 0522. This is ambiguous
|
// i.e., 105.22 W would be coded as 0522. This is ambiguous
|
||||||
|
|
|
||||||
|
|
@ -121,10 +121,20 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
||||||
// Direction: dirDEG
|
// Direction: dirDEG
|
||||||
std::string direction = tokenList.at(2);
|
std::string direction = tokenList.at(2);
|
||||||
if (direction.size() == 6 && direction.ends_with("DEG"))
|
if (direction.size() == 6 && direction.ends_with("DEG"))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
p->direction_ =
|
p->direction_ =
|
||||||
static_cast<uint16_t>(std::stoul(direction.substr(0, 3)));
|
static_cast<uint16_t>(std::stoul(direction.substr(0, 3)));
|
||||||
}
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid direction: \"" << direction << "\" ("
|
||||||
|
<< ex.what() << ")";
|
||||||
|
dataValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
|
@ -136,8 +146,17 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
||||||
std::string speed = tokenList.at(3);
|
std::string speed = tokenList.at(3);
|
||||||
if (speed.size() >= 3 && speed.size() <= 4 && speed.ends_with("KT"))
|
if (speed.size() >= 3 && speed.size() <= 4 && speed.ends_with("KT"))
|
||||||
{
|
{
|
||||||
p->speed_ =
|
try
|
||||||
static_cast<uint8_t>(std::stoul(speed.substr(0, speed.size() - 2)));
|
{
|
||||||
|
p->speed_ = static_cast<uint8_t>(
|
||||||
|
std::stoul(speed.substr(0, speed.size() - 2)));
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Invalid speed: \""
|
||||||
|
<< speed << "\" (" << ex.what() << ")";
|
||||||
|
dataValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -150,9 +169,23 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
||||||
for (auto token = tokenList.cbegin() + 4; token != tokenList.cend();
|
for (auto token = tokenList.cbegin() + 4; token != tokenList.cend();
|
||||||
++token)
|
++token)
|
||||||
{
|
{
|
||||||
double latitude = std::stod(*token) * 0.01;
|
double latitude = 0.0;
|
||||||
|
double longitude = 0.0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
latitude = std::stod(*token) * 0.01;
|
||||||
++token;
|
++token;
|
||||||
double longitude = std::stod(*token) * 0.01;
|
longitude = std::stod(*token) * 0.01;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
<< logPrefix_ << "Invalid location token: \"" << *token << "\" ("
|
||||||
|
<< ex.what() << ")";
|
||||||
|
dataValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// If a given product straddles 180 degrees longitude, those points
|
// If a given product straddles 180 degrees longitude, those points
|
||||||
// west of 180 degrees will be given as if they were west longitude
|
// west of 180 degrees will be given as if they were west longitude
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue