Look for specific impact based warning tags in text products

This commit is contained in:
Dan Paulat 2024-06-03 00:09:32 -05:00
parent 60aed45450
commit 9437b0bfce
5 changed files with 109 additions and 10 deletions

View file

@ -0,0 +1,24 @@
#pragma once
#include <string>
namespace scwx
{
namespace awips
{
enum class ThreatCategory
{
Base,
Significant,
Considerable,
Destructive,
Catastrophic,
Unknown
};
ThreatCategory GetThreatCategory(const std::string& name);
const std::string& GetThreatCategoryName(ThreatCategory threatCategory);
} // namespace awips
} // namespace scwx

View file

@ -2,6 +2,7 @@
#include <scwx/awips/coded_location.hpp> #include <scwx/awips/coded_location.hpp>
#include <scwx/awips/coded_time_motion_location.hpp> #include <scwx/awips/coded_time_motion_location.hpp>
#include <scwx/awips/impact_based_warnings.hpp>
#include <scwx/awips/message.hpp> #include <scwx/awips/message.hpp>
#include <scwx/awips/pvtec.hpp> #include <scwx/awips/pvtec.hpp>
#include <scwx/awips/ugc.hpp> #include <scwx/awips/ugc.hpp>
@ -56,15 +57,16 @@ struct SegmentHeader
struct Segment struct Segment
{ {
std::optional<SegmentHeader> header_; std::optional<SegmentHeader> header_ {};
std::vector<std::string> productContent_; std::vector<std::string> productContent_ {};
std::optional<CodedLocation> codedLocation_; std::optional<CodedLocation> codedLocation_ {};
std::optional<CodedTimeMotionLocation> codedMotion_; std::optional<CodedTimeMotionLocation> codedMotion_ {};
Segment() : bool observed_ {false};
header_ {}, productContent_ {}, codedLocation_ {}, codedMotion_ {} ThreatCategory threatCategory_ {ThreatCategory::Base};
{ bool tornadoPossible_ {false};
}
Segment() = default;
Segment(const Segment&) = delete; Segment(const Segment&) = delete;
Segment& operator=(const Segment&) = delete; Segment& operator=(const Segment&) = delete;

View file

@ -0,0 +1,31 @@
#include <scwx/awips/impact_based_warnings.hpp>
#include <scwx/util/enum.hpp>
#include <unordered_map>
#include <boost/algorithm/string.hpp>
namespace scwx
{
namespace awips
{
static const std::string logPrefix_ = "scwx::awips::impact_based_warnings";
static const std::unordered_map<ThreatCategory, std::string>
threatCategoryName_ {{ThreatCategory::Base, "Base"},
{ThreatCategory::Significant, "Significant"},
{ThreatCategory::Considerable, "Considerable"},
{ThreatCategory::Destructive, "Destructive"},
{ThreatCategory::Catastrophic, "Catastrophic"},
{ThreatCategory::Unknown, "?"}};
SCWX_GET_ENUM(ThreatCategory, GetThreatCategory, threatCategoryName_)
const std::string& GetThreatCategoryName(ThreatCategory threatCategory)
{
return threatCategoryName_.at(threatCategory);
}
} // namespace awips
} // namespace scwx

View file

@ -3,6 +3,7 @@
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
#include <scwx/util/streams.hpp> #include <scwx/util/streams.hpp>
#include <algorithm>
#include <istream> #include <istream>
#include <string> #include <string>
@ -304,6 +305,14 @@ void ParseCodedInformation(std::shared_ptr<Segment> segment,
{ {
typedef std::vector<std::string>::const_iterator StringIterator; typedef std::vector<std::string>::const_iterator StringIterator;
static constexpr std::size_t kThreatCategoryTagCount = 4;
static const std::array<std::string, kThreatCategoryTagCount>
kThreatCategoryTags {"FLASH FLOOD DAMAGE THREAT...",
"SNOW SQUALL IMPACT...",
"THUNDERSTORM DAMAGE THREAT...",
"TORNADO DAMAGE THREAT..."};
std::array<std::string, kThreatCategoryTagCount>::const_iterator threatTagIt;
std::vector<std::string>& productContent = segment->productContent_; std::vector<std::string>& productContent = segment->productContent_;
StringIterator codedLocationBegin = productContent.cend(); StringIterator codedLocationBegin = productContent.cend();
@ -325,8 +334,8 @@ void ParseCodedInformation(std::shared_ptr<Segment> segment,
codedLocationEnd = it; codedLocationEnd = it;
} }
if (codedMotionBegin == productContent.cend() && else if (codedMotionBegin == productContent.cend() &&
it->starts_with("TIME...MOT...LOC")) it->starts_with("TIME...MOT...LOC"))
{ {
codedMotionBegin = it; codedMotionBegin = it;
} }
@ -338,6 +347,37 @@ void ParseCodedInformation(std::shared_ptr<Segment> segment,
{ {
codedMotionEnd = it; codedMotionEnd = it;
} }
else if (!segment->observed_ &&
it->find("...OBSERVED") != std::string::npos)
{
segment->observed_ = true;
}
else if (!segment->tornadoPossible_ && *it == "TORNADO...POSSIBLE")
{
segment->tornadoPossible_ = true;
}
else if (segment->threatCategory_ == ThreatCategory::Base &&
(threatTagIt = std::find_if(kThreatCategoryTags.cbegin(),
kThreatCategoryTags.cend(),
[&it](const std::string& tag) {
return it->starts_with(tag);
})) != kThreatCategoryTags.cend() &&
it->length() > threatTagIt->length())
{
const std::string threatCategoryName =
it->substr(threatTagIt->length());
ThreatCategory threatCategory = GetThreatCategory(threatCategoryName);
if (threatCategory == ThreatCategory::Unknown)
{
threatCategory = ThreatCategory::Base;
}
segment->threatCategory_ = threatCategory;
}
} }
if (codedLocationBegin != productContent.cend()) if (codedLocationBegin != productContent.cend())

View file

@ -14,6 +14,7 @@ endif()
set(HDR_AWIPS include/scwx/awips/coded_location.hpp set(HDR_AWIPS include/scwx/awips/coded_location.hpp
include/scwx/awips/coded_time_motion_location.hpp include/scwx/awips/coded_time_motion_location.hpp
include/scwx/awips/impact_based_warnings.hpp
include/scwx/awips/message.hpp include/scwx/awips/message.hpp
include/scwx/awips/phenomenon.hpp include/scwx/awips/phenomenon.hpp
include/scwx/awips/pvtec.hpp include/scwx/awips/pvtec.hpp
@ -24,6 +25,7 @@ set(HDR_AWIPS include/scwx/awips/coded_location.hpp
include/scwx/awips/wmo_header.hpp) include/scwx/awips/wmo_header.hpp)
set(SRC_AWIPS source/scwx/awips/coded_location.cpp set(SRC_AWIPS source/scwx/awips/coded_location.cpp
source/scwx/awips/coded_time_motion_location.cpp source/scwx/awips/coded_time_motion_location.cpp
source/scwx/awips/impact_based_warnings.cpp
source/scwx/awips/message.cpp source/scwx/awips/message.cpp
source/scwx/awips/phenomenon.cpp source/scwx/awips/phenomenon.cpp
source/scwx/awips/pvtec.cpp source/scwx/awips/pvtec.cpp