Add year to Text Event Key

This commit is contained in:
Dan Paulat 2025-05-02 22:56:41 -05:00
parent 34fc6d584f
commit 228ec191f6
3 changed files with 56 additions and 8 deletions

View file

@ -275,6 +275,8 @@ void TextEventManager::SelectTime(
void TextEventManager::Impl::HandleMessage( void TextEventManager::Impl::HandleMessage(
const std::shared_ptr<awips::TextProductMessage>& message) const std::shared_ptr<awips::TextProductMessage>& message)
{ {
using namespace std::chrono_literals;
auto segments = message->segments(); auto segments = message->segments();
// If there are no segments, skip this message // If there are no segments, skip this message
@ -295,15 +297,35 @@ void TextEventManager::Impl::HandleMessage(
} }
} }
// Determine year
std::chrono::year_month_day wmoDate = std::chrono::floor<std::chrono::days>(
message->wmo_header()->GetDateTime());
std::chrono::year wmoYear = wmoDate.year();
std::unique_lock lock(textEventMutex_); std::unique_lock lock(textEventMutex_);
// Find a matching event in the event map // Find a matching event in the event map
auto& vtecString = segments[0]->header_->vtecString_; auto& vtecString = segments[0]->header_->vtecString_;
types::TextEventKey key {vtecString[0].pVtec_}; types::TextEventKey key {vtecString[0].pVtec_, wmoYear};
size_t messageIndex = 0; size_t messageIndex = 0;
auto it = textEventMap_.find(key); auto it = textEventMap_.find(key);
bool updated = false; bool updated = false;
if (
// If there was no matching event
it == textEventMap_.cend() &&
// The event is not new
vtecString[0].pVtec_.action() != awips::PVtec::Action::New &&
// The message was on January 1
wmoDate.month() == std::chrono::January && wmoDate.day() == 1d &&
// This is at least the 10th ETN of the year
vtecString[0].pVtec_.event_tracking_number() > 10)
{
// Attempt to find a matching event from last year
key = {vtecString[0].pVtec_, wmoYear - std::chrono::years {1}};
it = textEventMap_.find(key);
}
if (it == textEventMap_.cend()) if (it == textEventMap_.cend())
{ {
// If there was no matching event, add the message to a new event // If there was no matching event, add the message to a new event

View file

@ -14,26 +14,29 @@ static const std::string logPrefix_ = "scwx::qt::types::text_event_key";
std::string TextEventKey::ToFullString() const std::string TextEventKey::ToFullString() const
{ {
return fmt::format("{} {} {} {:04}", return fmt::format("{} {} {} {:04} ({:04})",
officeId_, officeId_,
awips::GetPhenomenonText(phenomenon_), awips::GetPhenomenonText(phenomenon_),
awips::GetSignificanceText(significance_), awips::GetSignificanceText(significance_),
etn_); etn_,
static_cast<int>(year_));
} }
std::string TextEventKey::ToString() const std::string TextEventKey::ToString() const
{ {
return fmt::format("{}.{}.{}.{:04}", return fmt::format("{}.{}.{}.{:04}.{:04}",
officeId_, officeId_,
awips::GetPhenomenonCode(phenomenon_), awips::GetPhenomenonCode(phenomenon_),
awips::GetSignificanceCode(significance_), awips::GetSignificanceCode(significance_),
etn_); etn_,
static_cast<int>(year_));
} }
bool TextEventKey::operator==(const TextEventKey& o) const bool TextEventKey::operator==(const TextEventKey& o) const
{ {
return (officeId_ == o.officeId_ && phenomenon_ == o.phenomenon_ && return (officeId_ == o.officeId_ && phenomenon_ == o.phenomenon_ &&
significance_ == o.significance_ && etn_ == o.etn_); significance_ == o.significance_ && etn_ == o.etn_ &&
year_ == o.year_);
} }
size_t TextEventHash<TextEventKey>::operator()(const TextEventKey& x) const size_t TextEventHash<TextEventKey>::operator()(const TextEventKey& x) const
@ -43,6 +46,7 @@ size_t TextEventHash<TextEventKey>::operator()(const TextEventKey& x) const
boost::hash_combine(seed, x.phenomenon_); boost::hash_combine(seed, x.phenomenon_);
boost::hash_combine(seed, x.significance_); boost::hash_combine(seed, x.significance_);
boost::hash_combine(seed, x.etn_); boost::hash_combine(seed, x.etn_);
boost::hash_combine(seed, static_cast<int>(x.year_));
return seed; return seed;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <scwx/awips/pvtec.hpp> #include <scwx/awips/pvtec.hpp>
#include <scwx/awips/wmo_header.hpp>
namespace scwx namespace scwx
{ {
@ -12,12 +13,32 @@ namespace types
struct TextEventKey struct TextEventKey
{ {
TextEventKey() : TextEventKey(awips::PVtec {}) {} TextEventKey() : TextEventKey(awips::PVtec {}) {}
TextEventKey(const awips::PVtec& pvtec) : TextEventKey(const awips::PVtec& pvtec, std::chrono::year yearHint = {}) :
officeId_ {pvtec.office_id()}, officeId_ {pvtec.office_id()},
phenomenon_ {pvtec.phenomenon()}, phenomenon_ {pvtec.phenomenon()},
significance_ {pvtec.significance()}, significance_ {pvtec.significance()},
etn_ {pvtec.event_tracking_number()} etn_ {pvtec.event_tracking_number()}
{ {
using namespace std::chrono_literals;
std::chrono::year_month_day ymd =
std::chrono::floor<std::chrono::days>(pvtec.event_begin());
if (ymd.year() > 1970y)
{
// Prefer the year from the event begin
year_ = ymd.year();
}
else if (yearHint > 1970y)
{
// Otherwise, use the year hint
year_ = yearHint;
}
else
{
// If there was no year hint, use the event end
ymd = std::chrono::floor<std::chrono::days>(pvtec.event_end());
year_ = ymd.year();
}
} }
std::string ToFullString() const; std::string ToFullString() const;
@ -27,7 +48,8 @@ struct TextEventKey
std::string officeId_; std::string officeId_;
awips::Phenomenon phenomenon_; awips::Phenomenon phenomenon_;
awips::Significance significance_; awips::Significance significance_;
int16_t etn_; std::int16_t etn_;
std::chrono::year year_;
}; };
template<class Key> template<class Key>