mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:50:06 +00:00
Starting to parse alphanumeric data from storm tracking information
This commit is contained in:
parent
2cd76d7da4
commit
0415223571
4 changed files with 156 additions and 1 deletions
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
#include <scwx/wsr88d/rpg/graphic_product_message.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
#include <units/velocity.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace wsr88d
|
||||
|
|
@ -12,6 +18,27 @@ namespace rpg
|
|||
class StormTrackingInformationMessage : public GraphicProductMessage
|
||||
{
|
||||
public:
|
||||
struct StiRecord
|
||||
{
|
||||
struct Position
|
||||
{
|
||||
std::optional<units::angle::degrees<float>> azimuth_ {};
|
||||
std::optional<units::length::nautical_miles<float>> range_ {};
|
||||
};
|
||||
|
||||
Position currentPosition_ {};
|
||||
std::optional<units::angle::degrees<float>> direction_;
|
||||
std::optional<units::velocity::knots<float>> speed_;
|
||||
|
||||
std::array<Position, 4> forecastPosition_ {};
|
||||
|
||||
std::optional<units::length::nautical_miles<float>> forecastError_ {};
|
||||
std::optional<units::length::nautical_miles<float>> meanError_ {};
|
||||
|
||||
std::optional<std::int16_t> maxDbz_ {};
|
||||
std::optional<units::length::feet<float>> maxDbzHeight_ {};
|
||||
};
|
||||
|
||||
explicit StormTrackingInformationMessage();
|
||||
~StormTrackingInformationMessage();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ public:
|
|||
|
||||
size_t data_size() const override;
|
||||
|
||||
const std::vector<std::vector<std::string>>& page_list() const;
|
||||
|
||||
bool Parse(std::istream& is);
|
||||
bool Parse(std::istream& is, bool skipHeader);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#include <scwx/wsr88d/rpg/storm_tracking_information_message.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/strings.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -17,6 +21,21 @@ class StormTrackingInformationMessage::Impl
|
|||
public:
|
||||
explicit Impl() {}
|
||||
~Impl() = default;
|
||||
|
||||
void ParseGraphicBlock(
|
||||
const std::shared_ptr<const GraphicAlphanumericBlock>& block);
|
||||
void ParseTabularBlock(
|
||||
const std::shared_ptr<const TabularAlphanumericBlock>& block);
|
||||
|
||||
void ParseStormPositionForecastPage(const std::vector<std::string>& page);
|
||||
void ParseStormCellTrackingDataPage(const std::vector<std::string>& page);
|
||||
|
||||
// STORM POSITION/FORECAST
|
||||
std::optional<std::uint16_t> radarId_ {};
|
||||
std::optional<std::chrono::sys_time<std::chrono::seconds>> dateTime_ {};
|
||||
std::optional<std::uint16_t> numStormCells_ {};
|
||||
|
||||
std::unordered_map<std::string, StiRecord> stiRecords_ {};
|
||||
};
|
||||
|
||||
StormTrackingInformationMessage::StormTrackingInformationMessage() :
|
||||
|
|
@ -34,9 +53,110 @@ bool StormTrackingInformationMessage::Parse(std::istream& is)
|
|||
{
|
||||
bool dataValid = GraphicProductMessage::Parse(is);
|
||||
|
||||
std::shared_ptr<GraphicAlphanumericBlock> graphicBlock = nullptr;
|
||||
std::shared_ptr<TabularAlphanumericBlock> tabularBlock = nullptr;
|
||||
|
||||
if (dataValid)
|
||||
{
|
||||
graphicBlock = graphic_block();
|
||||
tabularBlock = tabular_block();
|
||||
}
|
||||
|
||||
if (graphicBlock != nullptr)
|
||||
{
|
||||
p->ParseGraphicBlock(graphicBlock);
|
||||
}
|
||||
|
||||
if (tabularBlock != nullptr)
|
||||
{
|
||||
p->ParseTabularBlock(tabularBlock);
|
||||
}
|
||||
|
||||
return dataValid;
|
||||
}
|
||||
|
||||
void StormTrackingInformationMessage::Impl::ParseGraphicBlock(
|
||||
const std::shared_ptr<const GraphicAlphanumericBlock>& block)
|
||||
{
|
||||
// TODO
|
||||
(void) (block);
|
||||
}
|
||||
|
||||
void StormTrackingInformationMessage::Impl::ParseTabularBlock(
|
||||
const std::shared_ptr<const TabularAlphanumericBlock>& block)
|
||||
{
|
||||
static const std::string kStormPositionForecast_ = "STORM POSITION/FORECAST";
|
||||
static const std::string kStormCellTrackingData_ =
|
||||
"STORM CELL TRACKING/FORECAST ADAPTATION DATA";
|
||||
|
||||
for (auto& page : block->page_list())
|
||||
{
|
||||
if (page.empty())
|
||||
{
|
||||
logger_->warn("Unexpected empty page");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (page[0].find(kStormPositionForecast_) != std::string::npos)
|
||||
{
|
||||
ParseStormPositionForecastPage(page);
|
||||
}
|
||||
else if (page[0].find(kStormCellTrackingData_) != std::string::npos)
|
||||
{
|
||||
ParseStormCellTrackingDataPage(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StormTrackingInformationMessage::Impl::ParseStormPositionForecastPage(
|
||||
const std::vector<std::string>& page)
|
||||
{
|
||||
for (std::size_t i = 1; i < page.size(); ++i)
|
||||
{
|
||||
const std::string& line = page[i];
|
||||
|
||||
// clang-format off
|
||||
// " RADAR ID 308 DATE/TIME 12:11:21/02:15:38 NUMBER OF STORM CELLS 34"
|
||||
// clang-format on
|
||||
if (i == 1 && line.size() >= 74)
|
||||
{
|
||||
if (radarId_ == std::nullopt)
|
||||
{
|
||||
radarId_ =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(14, 3));
|
||||
}
|
||||
if (dateTime_ == std::nullopt)
|
||||
{
|
||||
static const std::string kDateTimeFormat_ {"%m:%d:%y/%H:%M:%S"};
|
||||
|
||||
dateTime_ = util::TryParseDateTime<std::chrono::seconds>(
|
||||
kDateTimeFormat_, line.substr(29, 17));
|
||||
}
|
||||
if (numStormCells_ == std::nullopt)
|
||||
{
|
||||
numStormCells_ =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(71, 3));
|
||||
}
|
||||
}
|
||||
// clang-format off
|
||||
// " V6 183/147 234/ 63 178/137 172/129 166/122 159/117 0.7/ 0.7"
|
||||
// clang-format on
|
||||
else if (i >= 7 && line.size() >= 80)
|
||||
{
|
||||
// TODO: STI Record
|
||||
std::string stormId = line.substr(2, 2);
|
||||
(void) (stormId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StormTrackingInformationMessage::Impl::ParseStormCellTrackingDataPage(
|
||||
const std::vector<std::string>& page)
|
||||
{
|
||||
// TODO
|
||||
(void) (page);
|
||||
}
|
||||
|
||||
std::shared_ptr<StormTrackingInformationMessage>
|
||||
StormTrackingInformationMessage::Create(Level3MessageHeader&& header,
|
||||
std::istream& is)
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ TabularAlphanumericBlock::TabularAlphanumericBlock() :
|
|||
TabularAlphanumericBlock::~TabularAlphanumericBlock() = default;
|
||||
|
||||
TabularAlphanumericBlock::TabularAlphanumericBlock(
|
||||
TabularAlphanumericBlock&&) noexcept = default;
|
||||
TabularAlphanumericBlock&&) noexcept = default;
|
||||
TabularAlphanumericBlock& TabularAlphanumericBlock::operator=(
|
||||
TabularAlphanumericBlock&&) noexcept = default;
|
||||
|
||||
|
|
@ -68,6 +68,12 @@ size_t TabularAlphanumericBlock::data_size() const
|
|||
return p->lengthOfBlock_;
|
||||
}
|
||||
|
||||
const std::vector<std::vector<std::string>>&
|
||||
TabularAlphanumericBlock::page_list() const
|
||||
{
|
||||
return p->pageList_;
|
||||
}
|
||||
|
||||
bool TabularAlphanumericBlock::Parse(std::istream& is)
|
||||
{
|
||||
return Parse(is, false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue