mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:50:06 +00:00
Add alert layer lines
This commit is contained in:
parent
037e0922b0
commit
b2d648e960
1 changed files with 186 additions and 7 deletions
|
|
@ -1,5 +1,8 @@
|
||||||
#include <scwx/qt/map/alert_layer.hpp>
|
#include <scwx/qt/map/alert_layer.hpp>
|
||||||
|
#include <scwx/qt/gl/draw/geo_lines.hpp>
|
||||||
#include <scwx/qt/manager/text_event_manager.hpp>
|
#include <scwx/qt/manager/text_event_manager.hpp>
|
||||||
|
#include <scwx/qt/settings/palette_settings.hpp>
|
||||||
|
#include <scwx/qt/util/color.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
@ -20,6 +23,8 @@ namespace map
|
||||||
static const std::string logPrefix_ = "scwx::qt::map::alert_layer";
|
static const std::string logPrefix_ = "scwx::qt::map::alert_layer";
|
||||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
|
static const boost::gil::rgba32f_pixel_t kBlack_ {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
|
||||||
template<class Key>
|
template<class Key>
|
||||||
struct AlertTypeHash;
|
struct AlertTypeHash;
|
||||||
|
|
||||||
|
|
@ -29,7 +34,7 @@ struct AlertTypeHash<std::pair<awips::Phenomenon, bool>>
|
||||||
size_t operator()(const std::pair<awips::Phenomenon, bool>& x) const;
|
size_t operator()(const std::pair<awips::Phenomenon, bool>& x) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AlertLayerHandler : QObject
|
class AlertLayerHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
@ -92,26 +97,83 @@ public:
|
||||||
std::mutex alertMutex_ {};
|
std::mutex alertMutex_ {};
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void AlertAdded(const std::shared_ptr<SegmentRecord>& segmentRecord,
|
||||||
|
awips::Phenomenon phenomenon);
|
||||||
|
void AlertUpdated(const std::shared_ptr<SegmentRecord>& segmentRecord);
|
||||||
void AlertsUpdated(awips::Phenomenon phenomenon, bool alertActive);
|
void AlertsUpdated(awips::Phenomenon phenomenon, bool alertActive);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AlertLayer::Impl
|
class AlertLayer::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Impl([[maybe_unused]] std::shared_ptr<MapContext> context,
|
explicit Impl(std::shared_ptr<MapContext> context,
|
||||||
awips::Phenomenon phenomenon) :
|
awips::Phenomenon phenomenon) :
|
||||||
phenomenon_ {phenomenon}
|
phenomenon_ {phenomenon},
|
||||||
|
borders_ {{false, std::make_shared<gl::draw::GeoLines>(context)},
|
||||||
|
{true, std::make_shared<gl::draw::GeoLines>(context)}},
|
||||||
|
lines_ {{false, std::make_shared<gl::draw::GeoLines>(context)},
|
||||||
|
{true, std::make_shared<gl::draw::GeoLines>(context)}}
|
||||||
{
|
{
|
||||||
}
|
auto& paletteSettings = settings::PaletteSettings::Instance();
|
||||||
~Impl() {};
|
|
||||||
|
|
||||||
awips::Phenomenon phenomenon_;
|
for (auto alertActive : {false, true})
|
||||||
|
{
|
||||||
|
lineColor_.emplace(
|
||||||
|
alertActive,
|
||||||
|
util::color::ToRgba8PixelT(
|
||||||
|
paletteSettings.alert_color(phenomenon_, alertActive)
|
||||||
|
.GetValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectSignals();
|
||||||
|
}
|
||||||
|
~Impl() { receiver_ = nullptr; };
|
||||||
|
|
||||||
|
void AddAlert(
|
||||||
|
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord);
|
||||||
|
void UpdateAlert(
|
||||||
|
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord);
|
||||||
|
void ConnectSignals();
|
||||||
|
|
||||||
|
static void AddLine(std::shared_ptr<gl::draw::GeoLines>& lines,
|
||||||
|
std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
||||||
|
const common::Coordinate& p1,
|
||||||
|
const common::Coordinate& p2,
|
||||||
|
boost::gil::rgba32f_pixel_t color,
|
||||||
|
float width,
|
||||||
|
std::chrono::system_clock::time_point startTime,
|
||||||
|
std::chrono::system_clock::time_point endTime);
|
||||||
|
static void
|
||||||
|
AddLines(std::shared_ptr<gl::draw::GeoLines>& lines,
|
||||||
|
const std::vector<common::Coordinate>& coordinates,
|
||||||
|
boost::gil::rgba32_pixel_t color,
|
||||||
|
float width,
|
||||||
|
std::chrono::system_clock::time_point startTime,
|
||||||
|
std::chrono::system_clock::time_point endTime,
|
||||||
|
std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems);
|
||||||
|
|
||||||
|
const awips::Phenomenon phenomenon_;
|
||||||
|
|
||||||
|
std::unique_ptr<QObject> receiver_ {std::make_unique<QObject>()};
|
||||||
|
|
||||||
|
std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> borders_;
|
||||||
|
std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> lines_;
|
||||||
|
|
||||||
|
std::unordered_map<bool, boost::gil::rgba8_pixel_t> lineColor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
AlertLayer::AlertLayer(std::shared_ptr<MapContext> context,
|
AlertLayer::AlertLayer(std::shared_ptr<MapContext> context,
|
||||||
awips::Phenomenon phenomenon) :
|
awips::Phenomenon phenomenon) :
|
||||||
DrawLayer(context), p(std::make_unique<Impl>(context, phenomenon))
|
DrawLayer(context), p(std::make_unique<Impl>(context, phenomenon))
|
||||||
{
|
{
|
||||||
|
for (auto alertActive : {false, true})
|
||||||
|
{
|
||||||
|
auto& borders = p->borders_.at(alertActive);
|
||||||
|
auto& lines = p->lines_.at(alertActive);
|
||||||
|
|
||||||
|
AddDrawItem(borders);
|
||||||
|
AddDrawItem(lines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertLayer::~AlertLayer() = default;
|
AlertLayer::~AlertLayer() = default;
|
||||||
|
|
@ -121,6 +183,18 @@ void AlertLayer::Initialize()
|
||||||
logger_->debug("Initialize: {}", awips::GetPhenomenonText(p->phenomenon_));
|
logger_->debug("Initialize: {}", awips::GetPhenomenonText(p->phenomenon_));
|
||||||
|
|
||||||
DrawLayer::Initialize();
|
DrawLayer::Initialize();
|
||||||
|
|
||||||
|
for (auto alertActive : {false, true})
|
||||||
|
{
|
||||||
|
auto& borders = p->borders_.at(alertActive);
|
||||||
|
auto& lines = p->lines_.at(alertActive);
|
||||||
|
|
||||||
|
borders->StartLines();
|
||||||
|
borders->FinishLines();
|
||||||
|
|
||||||
|
lines->StartLines();
|
||||||
|
lines->FinishLines();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlertLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
void AlertLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
||||||
|
|
@ -183,6 +257,8 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key,
|
||||||
if (segmentRecord->segmentEnd_ > segmentBegin)
|
if (segmentRecord->segmentEnd_ > segmentBegin)
|
||||||
{
|
{
|
||||||
segmentRecord->segmentEnd_ = segmentBegin;
|
segmentRecord->segmentEnd_ = segmentBegin;
|
||||||
|
|
||||||
|
Q_EMIT AlertUpdated(segmentRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,6 +286,8 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key,
|
||||||
segmentsForKey.push_back(segmentRecord);
|
segmentsForKey.push_back(segmentRecord);
|
||||||
segmentsForType.push_back(segmentRecord);
|
segmentsForType.push_back(segmentRecord);
|
||||||
|
|
||||||
|
Q_EMIT AlertAdded(segmentRecord, phenomenon);
|
||||||
|
|
||||||
alertsUpdated.emplace(phenomenon, alertActive);
|
alertsUpdated.emplace(phenomenon, alertActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,6 +301,107 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AlertLayer::Impl::ConnectSignals()
|
||||||
|
{
|
||||||
|
QObject::connect(
|
||||||
|
&AlertLayerHandler::Instance(),
|
||||||
|
&AlertLayerHandler::AlertAdded,
|
||||||
|
receiver_.get(),
|
||||||
|
[this](
|
||||||
|
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord,
|
||||||
|
awips::Phenomenon phenomenon)
|
||||||
|
{
|
||||||
|
if (phenomenon == phenomenon_)
|
||||||
|
{
|
||||||
|
AddAlert(segmentRecord);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlertLayer::Impl::AddAlert(
|
||||||
|
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord)
|
||||||
|
{
|
||||||
|
auto& segment = segmentRecord->segment_;
|
||||||
|
|
||||||
|
auto& vtec = segment->header_->vtecString_.front();
|
||||||
|
auto action = vtec.pVtec_.action();
|
||||||
|
bool alertActive = (action != awips::PVtec::Action::Canceled);
|
||||||
|
auto& startTime = segmentRecord->segmentBegin_;
|
||||||
|
auto& endTime = segmentRecord->segmentEnd_;
|
||||||
|
|
||||||
|
auto& lineColor = lineColor_.at(alertActive);
|
||||||
|
auto& lines = lines_.at(alertActive);
|
||||||
|
|
||||||
|
const auto& coordinates = segment->codedLocation_->coordinates();
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>> drawItems {};
|
||||||
|
|
||||||
|
AddLines(lines, coordinates, kBlack_, 5.0f, startTime, endTime, drawItems);
|
||||||
|
AddLines(lines, coordinates, lineColor, 3.0f, startTime, endTime, drawItems);
|
||||||
|
|
||||||
|
lines->FinishLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlertLayer::Impl::UpdateAlert(
|
||||||
|
[[maybe_unused]] const std::shared_ptr<AlertLayerHandler::SegmentRecord>&
|
||||||
|
segmentRecord)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlertLayer::Impl::AddLines(
|
||||||
|
std::shared_ptr<gl::draw::GeoLines>& lines,
|
||||||
|
const std::vector<common::Coordinate>& coordinates,
|
||||||
|
boost::gil::rgba32_pixel_t color,
|
||||||
|
float width,
|
||||||
|
std::chrono::system_clock::time_point startTime,
|
||||||
|
std::chrono::system_clock::time_point endTime,
|
||||||
|
std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0, j = 1; i < coordinates.size(); ++i, ++j)
|
||||||
|
{
|
||||||
|
if (j >= coordinates.size())
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
// Ignore repeated coordinates at the end
|
||||||
|
if (coordinates[i] == coordinates[j])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto di = lines->AddLine();
|
||||||
|
AddLine(lines,
|
||||||
|
di,
|
||||||
|
coordinates[i],
|
||||||
|
coordinates[j],
|
||||||
|
color,
|
||||||
|
width,
|
||||||
|
startTime,
|
||||||
|
endTime);
|
||||||
|
|
||||||
|
drawItems.push_back(di);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlertLayer::Impl::AddLine(std::shared_ptr<gl::draw::GeoLines>& lines,
|
||||||
|
std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
|
||||||
|
const common::Coordinate& p1,
|
||||||
|
const common::Coordinate& p2,
|
||||||
|
boost::gil::rgba32f_pixel_t color,
|
||||||
|
float width,
|
||||||
|
std::chrono::system_clock::time_point startTime,
|
||||||
|
std::chrono::system_clock::time_point endTime)
|
||||||
|
{
|
||||||
|
lines->SetLineLocation(
|
||||||
|
di, p1.latitude_, p1.longitude_, p2.latitude_, p2.longitude_);
|
||||||
|
lines->SetLineModulate(di, color);
|
||||||
|
lines->SetLineWidth(di, width);
|
||||||
|
lines->SetLineStartTime(di, startTime);
|
||||||
|
lines->SetLineEndTime(di, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
AlertLayerHandler& AlertLayerHandler::Instance()
|
AlertLayerHandler& AlertLayerHandler::Instance()
|
||||||
{
|
{
|
||||||
static AlertLayerHandler alertLayerHandler_ {};
|
static AlertLayerHandler alertLayerHandler_ {};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue