mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 23:30:04 +00:00
Initial alert model
This commit is contained in:
parent
5cf9746e97
commit
9afba385ea
3 changed files with 286 additions and 2 deletions
|
|
@ -84,11 +84,13 @@ set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp
|
|||
source/scwx/qt/map/overlay_layer.cpp
|
||||
source/scwx/qt/map/radar_product_layer.cpp
|
||||
source/scwx/qt/map/radar_range_layer.cpp)
|
||||
set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp
|
||||
set(HDR_MODEL source/scwx/qt/model/alert_model.hpp
|
||||
source/scwx/qt/model/radar_product_model.hpp
|
||||
source/scwx/qt/model/radar_site_model.hpp
|
||||
source/scwx/qt/model/tree_item.hpp
|
||||
source/scwx/qt/model/tree_model.hpp)
|
||||
set(SRC_MODEL source/scwx/qt/model/radar_product_model.cpp
|
||||
set(SRC_MODEL source/scwx/qt/model/alert_model.cpp
|
||||
source/scwx/qt/model/radar_product_model.cpp
|
||||
source/scwx/qt/model/radar_site_model.cpp
|
||||
source/scwx/qt/model/tree_item.cpp
|
||||
source/scwx/qt/model/tree_model.cpp)
|
||||
|
|
|
|||
237
scwx-qt/source/scwx/qt/model/alert_model.cpp
Normal file
237
scwx-qt/source/scwx/qt/model/alert_model.cpp
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
#include <scwx/qt/model/alert_model.hpp>
|
||||
#include <scwx/qt/common/types.hpp>
|
||||
#include <scwx/common/geographic.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::model::alert_model";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
static constexpr size_t kColumnEtn = 0u;
|
||||
static constexpr size_t kColumnOfficeId = 1u;
|
||||
static constexpr size_t kColumnPhenomenon = 2u;
|
||||
static constexpr size_t kColumnSignificance = 3u;
|
||||
static constexpr size_t kColumnState = 4u;
|
||||
static constexpr size_t kColumnCounties = 5u;
|
||||
static constexpr size_t kColumnStartTime = 6u;
|
||||
static constexpr size_t kColumnEndTime = 7u;
|
||||
static constexpr size_t kColumnDistance = 8u;
|
||||
static constexpr size_t kFirstColumn = kColumnEtn;
|
||||
static constexpr size_t kLastColumn = kColumnDistance;
|
||||
static constexpr size_t kNumColumns = 9u;
|
||||
|
||||
class AlertModelImpl
|
||||
{
|
||||
public:
|
||||
explicit AlertModelImpl();
|
||||
~AlertModelImpl() = default;
|
||||
|
||||
QList<types::TextEventKey> textEventKeys_;
|
||||
|
||||
GeographicLib::Geodesic geodesic_;
|
||||
|
||||
std::unordered_map<types::TextEventKey,
|
||||
double,
|
||||
types::TextEventHash<types::TextEventKey>>
|
||||
distanceMap_;
|
||||
scwx::common::DistanceType distanceDisplay_;
|
||||
scwx::common::Coordinate previousPosition_;
|
||||
};
|
||||
|
||||
AlertModel::AlertModel(QObject* parent) :
|
||||
QAbstractTableModel(parent), p(std::make_unique<AlertModelImpl>())
|
||||
{
|
||||
}
|
||||
AlertModel::~AlertModel() = default;
|
||||
|
||||
int AlertModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : p->textEventKeys_.size();
|
||||
}
|
||||
|
||||
int AlertModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : static_cast<int>(kNumColumns);
|
||||
}
|
||||
|
||||
QVariant AlertModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (index.isValid() && index.row() >= 0 &&
|
||||
index.row() < p->textEventKeys_.size() &&
|
||||
(role == Qt::DisplayRole || role == common::SortRole))
|
||||
{
|
||||
const auto& textEventKey = p->textEventKeys_.at(index.row());
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case kColumnEtn:
|
||||
return textEventKey.etn_;
|
||||
case kColumnOfficeId:
|
||||
return QString::fromStdString(textEventKey.officeId_);
|
||||
case kColumnPhenomenon:
|
||||
return QString::fromStdString(
|
||||
awips::GetPhenomenonText(textEventKey.phenomenon_));
|
||||
case kColumnSignificance:
|
||||
return QString::fromStdString(
|
||||
awips::GetSignificanceText(textEventKey.significance_));
|
||||
case kColumnState:
|
||||
return QString::fromStdString("?");
|
||||
case kColumnCounties:
|
||||
return QString::fromStdString("?");
|
||||
case kColumnStartTime:
|
||||
return QString::fromStdString("?");
|
||||
case kColumnEndTime:
|
||||
return QString::fromStdString("?");
|
||||
case kColumnDistance:
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (p->distanceDisplay_ == scwx::common::DistanceType::Miles)
|
||||
{
|
||||
return QString("%1 mi").arg(
|
||||
static_cast<uint32_t>(p->distanceMap_.at(textEventKey) *
|
||||
scwx::common::kMilesPerMeter));
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString("%1 km").arg(
|
||||
static_cast<uint32_t>(p->distanceMap_.at(textEventKey) *
|
||||
scwx::common::kKilometersPerMeter));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return p->distanceMap_.at(textEventKey);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant
|
||||
AlertModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case kColumnEtn:
|
||||
return tr("ETN");
|
||||
case kColumnOfficeId:
|
||||
return tr("Office ID");
|
||||
case kColumnPhenomenon:
|
||||
return tr("Phenomenon");
|
||||
case kColumnSignificance:
|
||||
return tr("Significance");
|
||||
case kColumnState:
|
||||
return tr("State");
|
||||
case kColumnCounties:
|
||||
return tr("Counties");
|
||||
case kColumnStartTime:
|
||||
return tr("Start Time");
|
||||
case kColumnEndTime:
|
||||
return tr("End Time");
|
||||
case kColumnDistance:
|
||||
return tr("Distance");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void AlertModel::HandleAlert(const types::TextEventKey& alertKey)
|
||||
{
|
||||
logger_->trace("Handle alert: {}, {}, {}, {}",
|
||||
alertKey.etn_,
|
||||
alertKey.officeId_,
|
||||
awips::GetPhenomenonText(alertKey.phenomenon_),
|
||||
awips::GetSignificanceText(alertKey.significance_));
|
||||
|
||||
double distanceInMeters;
|
||||
|
||||
if (!p->textEventKeys_.contains(alertKey))
|
||||
{
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
|
||||
p->textEventKeys_.push_back(alertKey);
|
||||
|
||||
p->geodesic_.Inverse(p->previousPosition_.latitude_,
|
||||
p->previousPosition_.longitude_,
|
||||
0.0, // TODO: textEvent->latitude(),
|
||||
0.0, // TODO: textEvent->longitude(),
|
||||
distanceInMeters);
|
||||
|
||||
p->distanceMap_[alertKey] = distanceInMeters;
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
else
|
||||
{
|
||||
p->geodesic_.Inverse(p->previousPosition_.latitude_,
|
||||
p->previousPosition_.longitude_,
|
||||
0.0, // TODO: textEvent->latitude(),
|
||||
0.0, // TODO: textEvent->longitude(),
|
||||
distanceInMeters);
|
||||
|
||||
const int row = 0; // TODO
|
||||
QModelIndex topLeft = createIndex(row, kFirstColumn);
|
||||
QModelIndex bottomRight = createIndex(row, kLastColumn);
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
void AlertModel::HandleMapUpdate(double latitude, double longitude)
|
||||
{
|
||||
logger_->trace("Handle map update: {}, {}", latitude, longitude);
|
||||
|
||||
double distanceInMeters;
|
||||
|
||||
for (const auto& textEvent : p->textEventKeys_)
|
||||
{
|
||||
p->geodesic_.Inverse(latitude,
|
||||
longitude,
|
||||
0.0, // TODO: textEvent->latitude(),
|
||||
0.0, // TODO: textEvent->longitude(),
|
||||
distanceInMeters);
|
||||
p->distanceMap_[textEvent] = distanceInMeters;
|
||||
}
|
||||
|
||||
p->previousPosition_ = {latitude, longitude};
|
||||
|
||||
QModelIndex topLeft = createIndex(0, kColumnDistance);
|
||||
QModelIndex bottomRight = createIndex(rowCount() - 1, kColumnDistance);
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
AlertModelImpl::AlertModelImpl() :
|
||||
textEventKeys_ {},
|
||||
geodesic_(GeographicLib::Constants::WGS84_a(),
|
||||
GeographicLib::Constants::WGS84_f()),
|
||||
distanceMap_ {},
|
||||
distanceDisplay_ {scwx::common::DistanceType::Miles},
|
||||
previousPosition_ {}
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
45
scwx-qt/source/scwx/qt/model/alert_model.hpp
Normal file
45
scwx-qt/source/scwx/qt/model/alert_model.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/qt/types/text_event_key.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
class AlertModelImpl;
|
||||
|
||||
class AlertModel : public QAbstractTableModel
|
||||
{
|
||||
public:
|
||||
explicit AlertModel(QObject* parent = nullptr);
|
||||
~AlertModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void HandleAlert(const types::TextEventKey& alertKey);
|
||||
void HandleMapUpdate(double latitude, double longitude);
|
||||
|
||||
private:
|
||||
std::unique_ptr<AlertModelImpl> p;
|
||||
|
||||
friend class AlertModelImpl;
|
||||
};
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
Loading…
Add table
Add a link
Reference in a new issue