From fdd981899f2805c665353605043b265b069035ac Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 14 Oct 2022 23:41:25 -0500 Subject: [PATCH] Add additional alert display columns - State, counties, start and end time --- scwx-qt/source/scwx/qt/main/main_window.ui | 3 + .../scwx/qt/manager/text_event_manager.cpp | 18 ++++-- scwx-qt/source/scwx/qt/model/alert_model.cpp | 64 ++++++++++++++++--- .../source/scwx/qt/types/text_event_key.cpp | 11 ++++ .../source/scwx/qt/types/text_event_key.hpp | 3 +- wxdata/include/scwx/util/strings.hpp | 14 ++++ wxdata/source/scwx/util/strings.cpp | 26 ++++++++ wxdata/wxdata.cmake | 2 + 8 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 wxdata/include/scwx/util/strings.hpp create mode 100644 wxdata/source/scwx/util/strings.cpp diff --git a/scwx-qt/source/scwx/qt/main/main_window.ui b/scwx-qt/source/scwx/qt/main/main_window.ui index 878e39bd..df7dac09 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.ui +++ b/scwx-qt/source/scwx/qt/main/main_window.ui @@ -355,6 +355,9 @@ Filter + + true + diff --git a/scwx-qt/source/scwx/qt/manager/text_event_manager.cpp b/scwx-qt/source/scwx/qt/manager/text_event_manager.cpp index eb64867a..232e2edb 100644 --- a/scwx-qt/source/scwx/qt/manager/text_event_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/text_event_manager.cpp @@ -86,14 +86,24 @@ void TextEventManager::Impl::HandleMessage( { auto segments = message->segments(); - // If there are no segments, if the first segment has no header, or if there - // is no VTEC string, skip this message - if (segments.empty() || !segments[0]->header_.has_value() || - segments[0]->header_->vtecString_.empty()) + // If there are no segments, skip this message + if (segments.empty()) { return; } + for (auto& segment : segments) + { + // If a segment has no header, or if there is no VTEC string, skip this + // message. A segmented message corresponding to a text event should have + // this information. + if (!segment->header_.has_value() || + segment->header_->vtecString_.empty()) + { + return; + } + } + std::unique_lock lock(textEventMutex_); // Find a matching event in the event map diff --git a/scwx-qt/source/scwx/qt/model/alert_model.cpp b/scwx-qt/source/scwx/qt/model/alert_model.cpp index 3283da57..4c23d4a0 100644 --- a/scwx-qt/source/scwx/qt/model/alert_model.cpp +++ b/scwx-qt/source/scwx/qt/model/alert_model.cpp @@ -1,7 +1,10 @@ #include +#include #include #include #include +#include +#include #include @@ -36,6 +39,11 @@ public: explicit AlertModelImpl(); ~AlertModelImpl() = default; + static std::string GetCounties(const types::TextEventKey& key); + static std::string GetState(const types::TextEventKey& key); + static std::string GetStartTime(const types::TextEventKey& key); + static std::string GetEndTime(const types::TextEventKey& key); + QList textEventKeys_; GeographicLib::Geodesic geodesic_; @@ -85,13 +93,16 @@ QVariant AlertModel::data(const QModelIndex& index, int role) const return QString::fromStdString( awips::GetSignificanceText(textEventKey.significance_)); case kColumnState: - return QString::fromStdString("?"); + return QString::fromStdString(AlertModelImpl::GetState(textEventKey)); case kColumnCounties: - return QString::fromStdString("?"); + return QString::fromStdString( + AlertModelImpl::GetCounties(textEventKey)); case kColumnStartTime: - return QString::fromStdString("?"); + return QString::fromStdString( + AlertModelImpl::GetStartTime(textEventKey)); case kColumnEndTime: - return QString::fromStdString("?"); + return QString::fromStdString( + AlertModelImpl::GetEndTime(textEventKey)); case kColumnDistance: if (role == Qt::DisplayRole) { @@ -158,11 +169,7 @@ AlertModel::headerData(int section, Qt::Orientation orientation, int role) const void AlertModel::HandleAlert(const types::TextEventKey& alertKey) { - logger_->trace("Handle alert: {}, {}, {}, {}", - alertKey.etn_, - alertKey.officeId_, - awips::GetPhenomenonText(alertKey.phenomenon_), - awips::GetSignificanceText(alertKey.significance_)); + logger_->trace("Handle alert: {}", alertKey.ToString()); double distanceInMeters; @@ -190,7 +197,7 @@ void AlertModel::HandleAlert(const types::TextEventKey& alertKey) 0.0, // TODO: textEvent->longitude(), distanceInMeters); - const int row = 0; // TODO + const int row = p->textEventKeys_.indexOf(alertKey); QModelIndex topLeft = createIndex(row, kFirstColumn); QModelIndex bottomRight = createIndex(row, kLastColumn); @@ -232,6 +239,43 @@ AlertModelImpl::AlertModelImpl() : { } +std::string AlertModelImpl::GetCounties(const types::TextEventKey& key) +{ + auto messageList = manager::TextEventManager::Instance().message_list(key); + auto& lastMessage = messageList.back(); + size_t segmentCount = lastMessage->segment_count(); + auto lastSegment = lastMessage->segment(segmentCount - 1); + return util::ToString(lastSegment->header_->ugc_.fips_ids()); +} + +std::string AlertModelImpl::GetState(const types::TextEventKey& key) +{ + auto messageList = manager::TextEventManager::Instance().message_list(key); + auto& lastMessage = messageList.back(); + size_t segmentCount = lastMessage->segment_count(); + auto lastSegment = lastMessage->segment(segmentCount - 1); + return util::ToString(lastSegment->header_->ugc_.states()); +} + +std::string AlertModelImpl::GetStartTime(const types::TextEventKey& key) +{ + auto messageList = manager::TextEventManager::Instance().message_list(key); + auto& firstMessage = messageList.front(); + auto firstSegment = firstMessage->segment(0); + return util::TimeString( + firstSegment->header_->vtecString_[0].pVtec_.event_begin()); +} + +std::string AlertModelImpl::GetEndTime(const types::TextEventKey& key) +{ + auto messageList = manager::TextEventManager::Instance().message_list(key); + auto& lastMessage = messageList.back(); + size_t segmentCount = lastMessage->segment_count(); + auto lastSegment = lastMessage->segment(segmentCount - 1); + return util::TimeString( + lastSegment->header_->vtecString_[0].pVtec_.event_end()); +} + } // namespace model } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/text_event_key.cpp b/scwx-qt/source/scwx/qt/types/text_event_key.cpp index 02775c13..0e5b189f 100644 --- a/scwx-qt/source/scwx/qt/types/text_event_key.cpp +++ b/scwx-qt/source/scwx/qt/types/text_event_key.cpp @@ -1,5 +1,7 @@ #include +#include + #include namespace scwx @@ -11,6 +13,15 @@ namespace types static const std::string logPrefix_ = "scwx::qt::types::text_event_key"; +std::string TextEventKey::ToString() const +{ + return std::format("{}, {}, {}, {}", + officeId_, + awips::GetPhenomenonText(phenomenon_), + awips::GetSignificanceText(significance_), + etn_); +} + bool TextEventKey::operator==(const TextEventKey& o) const { return (officeId_ == o.officeId_ && phenomenon_ == o.phenomenon_ && diff --git a/scwx-qt/source/scwx/qt/types/text_event_key.hpp b/scwx-qt/source/scwx/qt/types/text_event_key.hpp index 02b960a4..1925b5ee 100644 --- a/scwx-qt/source/scwx/qt/types/text_event_key.hpp +++ b/scwx-qt/source/scwx/qt/types/text_event_key.hpp @@ -19,7 +19,8 @@ struct TextEventKey { } - bool operator==(const TextEventKey& o) const; + std::string ToString() const; + bool operator==(const TextEventKey& o) const; std::string officeId_; awips::Phenomenon phenomenon_; diff --git a/wxdata/include/scwx/util/strings.hpp b/wxdata/include/scwx/util/strings.hpp new file mode 100644 index 00000000..0a5cc43f --- /dev/null +++ b/wxdata/include/scwx/util/strings.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace scwx +{ +namespace util +{ + +std::string ToString(const std::vector& v); + +} // namespace util +} // namespace scwx diff --git a/wxdata/source/scwx/util/strings.cpp b/wxdata/source/scwx/util/strings.cpp new file mode 100644 index 00000000..3a72c993 --- /dev/null +++ b/wxdata/source/scwx/util/strings.cpp @@ -0,0 +1,26 @@ +#include + +namespace scwx +{ +namespace util +{ + +std::string ToString(const std::vector& v) +{ + std::string value {}; + + for (const std::string& s : v) + { + if (!value.empty()) + { + value += ", "; + } + + value += s; + } + + return value; +} + +} // namespace util +} // namespace scwx diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 7a2703f4..e69496db 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -58,6 +58,7 @@ set(HDR_UTIL include/scwx/util/environment.hpp include/scwx/util/map.hpp include/scwx/util/rangebuf.hpp include/scwx/util/streams.hpp + include/scwx/util/strings.hpp include/scwx/util/threads.hpp include/scwx/util/time.hpp include/scwx/util/vectorbuf.hpp) @@ -67,6 +68,7 @@ set(SRC_UTIL source/scwx/util/environment.cpp source/scwx/util/logger.cpp source/scwx/util/rangebuf.cpp source/scwx/util/streams.cpp + source/scwx/util/strings.cpp source/scwx/util/time.cpp source/scwx/util/threads.cpp source/scwx/util/vectorbuf.cpp)