mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:20:04 +00:00
Add Storm Tracking Information display to Overlay Product Layer
This commit is contained in:
parent
a0701df13f
commit
900267b16f
2 changed files with 264 additions and 2 deletions
|
|
@ -1,4 +1,12 @@
|
|||
#include <scwx/qt/map/overlay_product_layer.hpp>
|
||||
#include <scwx/qt/gl/draw/linked_vectors.hpp>
|
||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||
#include <scwx/qt/view/overlay_product_view.hpp>
|
||||
#include <scwx/wsr88d/rpg/graphic_product_message.hpp>
|
||||
#include <scwx/wsr88d/rpg/linked_vector_packet.hpp>
|
||||
#include <scwx/wsr88d/rpg/rpg_types.hpp>
|
||||
#include <scwx/wsr88d/rpg/scit_data_packet.hpp>
|
||||
#include <scwx/wsr88d/rpg/storm_id_symbol_packet.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
namespace scwx
|
||||
|
|
@ -14,13 +22,54 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
|||
class OverlayProductLayer::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(std::shared_ptr<MapContext> context) {}
|
||||
explicit Impl(OverlayProductLayer* self,
|
||||
const std::shared_ptr<MapContext>& context) :
|
||||
self_ {self},
|
||||
linkedVectors_ {std::make_shared<gl::draw::LinkedVectors>(context)}
|
||||
{
|
||||
}
|
||||
~Impl() = default;
|
||||
|
||||
void UpdateStormTrackingInformation();
|
||||
|
||||
static void HandleLinkedVectorPacket(
|
||||
const std::shared_ptr<wsr88d::rpg::Packet>& packet,
|
||||
const common::Coordinate& center,
|
||||
const std::string& hoverText,
|
||||
boost::gil::rgba32f_pixel_t color,
|
||||
std::shared_ptr<gl::draw::LinkedVectors>& linkedVectors);
|
||||
static void HandleScitDataPacket(
|
||||
const std::shared_ptr<wsr88d::rpg::Packet>& packet,
|
||||
const common::Coordinate& center,
|
||||
const std::string& stormId,
|
||||
std::shared_ptr<gl::draw::LinkedVectors>& linkedVectors);
|
||||
static void
|
||||
HandleStormIdPacket(const std::shared_ptr<wsr88d::rpg::Packet>& packet,
|
||||
std::string& stormId);
|
||||
|
||||
OverlayProductLayer* self_;
|
||||
|
||||
bool stiNeedsUpdate_ {false};
|
||||
|
||||
std::shared_ptr<gl::draw::LinkedVectors> linkedVectors_;
|
||||
};
|
||||
|
||||
OverlayProductLayer::OverlayProductLayer(std::shared_ptr<MapContext> context) :
|
||||
DrawLayer(context), p(std::make_unique<Impl>(context))
|
||||
DrawLayer(context), p(std::make_unique<Impl>(this, context))
|
||||
{
|
||||
auto overlayProductView = context->overlay_product_view();
|
||||
connect(overlayProductView.get(),
|
||||
&view::OverlayProductView::ProductUpdated,
|
||||
this,
|
||||
[this](std::string product)
|
||||
{
|
||||
if (product == "NST")
|
||||
{
|
||||
p->stiNeedsUpdate_ = true;
|
||||
}
|
||||
});
|
||||
|
||||
AddDrawItem(p->linkedVectors_);
|
||||
}
|
||||
|
||||
OverlayProductLayer::~OverlayProductLayer() = default;
|
||||
|
|
@ -29,6 +78,8 @@ void OverlayProductLayer::Initialize()
|
|||
{
|
||||
logger_->debug("Initialize()");
|
||||
|
||||
p->UpdateStormTrackingInformation();
|
||||
|
||||
DrawLayer::Initialize();
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +91,11 @@ void OverlayProductLayer::Render(
|
|||
// Set OpenGL blend mode for transparency
|
||||
gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (p->stiNeedsUpdate_)
|
||||
{
|
||||
p->UpdateStormTrackingInformation();
|
||||
}
|
||||
|
||||
DrawLayer::Render(params);
|
||||
|
||||
SCWX_GL_CHECK_ERROR();
|
||||
|
|
@ -52,6 +108,170 @@ void OverlayProductLayer::Deinitialize()
|
|||
DrawLayer::Deinitialize();
|
||||
}
|
||||
|
||||
void OverlayProductLayer::Impl::UpdateStormTrackingInformation()
|
||||
{
|
||||
logger_->debug("Update Storm Tracking Information");
|
||||
|
||||
stiNeedsUpdate_ = false;
|
||||
|
||||
auto overlayProductView = self_->context()->overlay_product_view();
|
||||
auto radarProductManager = overlayProductView->radar_product_manager();
|
||||
auto record = overlayProductView->radar_product_record("NST");
|
||||
|
||||
float latitude = 0.0f;
|
||||
float longitude = 0.0f;
|
||||
|
||||
std::shared_ptr<wsr88d::Level3File> l3File = nullptr;
|
||||
std::shared_ptr<wsr88d::rpg::GraphicProductMessage> gpm = nullptr;
|
||||
std::shared_ptr<wsr88d::rpg::ProductSymbologyBlock> psb = nullptr;
|
||||
if (record != nullptr)
|
||||
{
|
||||
l3File = record->level3_file();
|
||||
}
|
||||
if (l3File != nullptr)
|
||||
{
|
||||
gpm = std::dynamic_pointer_cast<wsr88d::rpg::GraphicProductMessage>(
|
||||
l3File->message());
|
||||
}
|
||||
if (gpm != nullptr)
|
||||
{
|
||||
psb = gpm->symbology_block();
|
||||
}
|
||||
|
||||
linkedVectors_->StartVectors();
|
||||
|
||||
if (psb != nullptr)
|
||||
{
|
||||
std::shared_ptr<config::RadarSite> radarSite = nullptr;
|
||||
if (radarProductManager != nullptr)
|
||||
{
|
||||
radarSite = radarProductManager->radar_site();
|
||||
}
|
||||
if (radarSite != nullptr)
|
||||
{
|
||||
latitude = radarSite->latitude();
|
||||
longitude = radarSite->longitude();
|
||||
}
|
||||
|
||||
std::string stormId = "?";
|
||||
|
||||
for (std::size_t i = 0; i < psb->number_of_layers(); ++i)
|
||||
{
|
||||
auto packetList = psb->packet_list(static_cast<std::uint16_t>(i));
|
||||
for (auto& packet : packetList)
|
||||
{
|
||||
switch (packet->packet_code())
|
||||
{
|
||||
case static_cast<std::uint16_t>(wsr88d::rpg::PacketCode::StormId):
|
||||
HandleStormIdPacket(packet, stormId);
|
||||
break;
|
||||
|
||||
case static_cast<std::uint16_t>(
|
||||
wsr88d::rpg::PacketCode::ScitPastData):
|
||||
case static_cast<std::uint16_t>(
|
||||
wsr88d::rpg::PacketCode::ScitForecastData):
|
||||
HandleScitDataPacket(
|
||||
packet, {latitude, longitude}, stormId, linkedVectors_);
|
||||
break;
|
||||
|
||||
default:
|
||||
logger_->trace("Ignoring packet type: {}",
|
||||
packet->packet_code());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->trace("No Storm Tracking Information found");
|
||||
}
|
||||
|
||||
linkedVectors_->FinishVectors();
|
||||
}
|
||||
|
||||
void OverlayProductLayer::Impl::HandleStormIdPacket(
|
||||
const std::shared_ptr<wsr88d::rpg::Packet>& packet, std::string& stormId)
|
||||
{
|
||||
auto stormIdPacket =
|
||||
std::dynamic_pointer_cast<wsr88d::rpg::StormIdSymbolPacket>(packet);
|
||||
|
||||
if (stormIdPacket != nullptr && stormIdPacket->RecordCount() > 0)
|
||||
{
|
||||
stormId = stormIdPacket->storm_id(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Invalid Storm ID Packet");
|
||||
|
||||
stormId = "?";
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayProductLayer::Impl::HandleScitDataPacket(
|
||||
const std::shared_ptr<wsr88d::rpg::Packet>& packet,
|
||||
const common::Coordinate& center,
|
||||
const std::string& stormId,
|
||||
std::shared_ptr<gl::draw::LinkedVectors>& linkedVectors)
|
||||
{
|
||||
auto scitDataPacket =
|
||||
std::dynamic_pointer_cast<wsr88d::rpg::ScitDataPacket>(packet);
|
||||
|
||||
if (scitDataPacket != nullptr)
|
||||
{
|
||||
boost::gil::rgba32f_pixel_t color {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
if (scitDataPacket->packet_code() ==
|
||||
static_cast<std::uint16_t>(wsr88d::rpg::PacketCode::ScitPastData))
|
||||
{
|
||||
color = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
}
|
||||
|
||||
for (auto& subpacket : scitDataPacket->packet_list())
|
||||
{
|
||||
switch (subpacket->packet_code())
|
||||
{
|
||||
case static_cast<std::uint16_t>(
|
||||
wsr88d::rpg::PacketCode::LinkedVectorNoValue):
|
||||
HandleLinkedVectorPacket(
|
||||
subpacket, center, stormId, color, linkedVectors);
|
||||
break;
|
||||
|
||||
default:
|
||||
logger_->trace("Ignoring SCIT subpacket type: {}",
|
||||
subpacket->packet_code());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Invalid SCIT Data Packet");
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayProductLayer::Impl::HandleLinkedVectorPacket(
|
||||
const std::shared_ptr<wsr88d::rpg::Packet>& packet,
|
||||
const common::Coordinate& center,
|
||||
const std::string& hoverText,
|
||||
boost::gil::rgba32f_pixel_t color,
|
||||
std::shared_ptr<gl::draw::LinkedVectors>& linkedVectors)
|
||||
{
|
||||
auto linkedVectorPacket =
|
||||
std::dynamic_pointer_cast<wsr88d::rpg::LinkedVectorPacket>(packet);
|
||||
|
||||
if (linkedVectorPacket != nullptr)
|
||||
{
|
||||
auto di = linkedVectors->AddVector(center, linkedVectorPacket);
|
||||
gl::draw::LinkedVectors::SetVectorWidth(di, 1.0f);
|
||||
gl::draw::LinkedVectors::SetVectorModulate(di, color);
|
||||
gl::draw::LinkedVectors::SetVectorHoverText(di, hoverText);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Invalid Linked Vector Packet");
|
||||
}
|
||||
}
|
||||
|
||||
bool OverlayProductLayer::RunMousePicking(
|
||||
const QMapLibreGL::CustomLayerRenderParameters& params,
|
||||
const QPointF& mouseLocalPos,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,48 @@ namespace wsr88d
|
|||
namespace rpg
|
||||
{
|
||||
|
||||
enum class PacketCode : std::uint16_t
|
||||
{
|
||||
TextNoValue = 1,
|
||||
SpecialSymbol = 2,
|
||||
MesocycloneSymbol3 = 3,
|
||||
WindBarbData = 4,
|
||||
VectorArrowData = 5,
|
||||
LinkedVectorNoValue = 6,
|
||||
UnlinkedVectorNoValue = 7,
|
||||
TextUniform = 8,
|
||||
LinkedVectorUniform = 9,
|
||||
UnlinkedVectorUniform = 10,
|
||||
MesocycloneSymbol11 = 11,
|
||||
TornadoVortexSignatureSymbol = 12,
|
||||
HailPositiveSymbol = 13,
|
||||
HailProbableSymbol = 14,
|
||||
StormId = 15,
|
||||
DigitalRadialDataArray = 16,
|
||||
DigitalPrecipitationDataArray = 17,
|
||||
PrecipitationRateDataArray = 18,
|
||||
HdaHailSymbol = 19,
|
||||
PointFeatureSymbol = 20,
|
||||
CellTrendData = 21,
|
||||
CellTrendVolumeScanTimes = 22,
|
||||
ScitPastData = 23,
|
||||
ScitForecastData = 24,
|
||||
StiCircle = 25,
|
||||
ElevatedTornadoVortexSignatureSymbol = 26,
|
||||
GenericData28 = 28,
|
||||
GenericData29 = 29,
|
||||
SetColorLevel = 0x0802,
|
||||
LinkedContourVector = 0x0E03,
|
||||
UnlinkedContourVector = 0x3501,
|
||||
MapMessage0E23 = 0x0E23,
|
||||
MapMessage3521 = 0x3521,
|
||||
MapMessage4E00 = 0x4E00,
|
||||
MapMessage4E01 = 0x4E01,
|
||||
RadialData = 0xAF1F,
|
||||
RasterDataBA07 = 0xBA07,
|
||||
RasterDataBA0F = 0xBA0F
|
||||
};
|
||||
|
||||
enum class SpecialSymbol
|
||||
{
|
||||
PastStormCellPosition,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue