Special graphic symbol packet

This commit is contained in:
Dan Paulat 2022-01-09 15:03:31 -06:00
parent 6d4428b8e0
commit cbb3ec0368
18 changed files with 1380 additions and 0 deletions

View file

@ -0,0 +1,48 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class HdaHailSymbolPacketImpl;
class HdaHailSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit HdaHailSymbolPacket();
~HdaHailSymbolPacket();
HdaHailSymbolPacket(const HdaHailSymbolPacket&) = delete;
HdaHailSymbolPacket& operator=(const HdaHailSymbolPacket&) = delete;
HdaHailSymbolPacket(HdaHailSymbolPacket&&) noexcept;
HdaHailSymbolPacket& operator=(HdaHailSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
int16_t probability_of_hail(size_t i) const;
int16_t probability_of_severe_hail(size_t i) const;
uint16_t max_hail_size(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<HdaHailSymbolPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<HdaHailSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,46 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class MesocycloneSymbolPacketImpl;
class MesocycloneSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit MesocycloneSymbolPacket();
~MesocycloneSymbolPacket();
MesocycloneSymbolPacket(const MesocycloneSymbolPacket&) = delete;
MesocycloneSymbolPacket& operator=(const MesocycloneSymbolPacket&) = delete;
MesocycloneSymbolPacket(MesocycloneSymbolPacket&&) noexcept;
MesocycloneSymbolPacket& operator=(MesocycloneSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
int16_t radius_of_mesocyclone(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<MesocycloneSymbolPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<MesocycloneSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,51 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class PointFeatureSymbolPacketImpl;
class PointFeatureSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit PointFeatureSymbolPacket();
~PointFeatureSymbolPacket();
PointFeatureSymbolPacket(const PointFeatureSymbolPacket&) = delete;
PointFeatureSymbolPacket&
operator=(const PointFeatureSymbolPacket&) = delete;
PointFeatureSymbolPacket(PointFeatureSymbolPacket&&) noexcept;
PointFeatureSymbolPacket& operator=(PointFeatureSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
uint16_t point_feature_type(size_t i) const;
uint16_t point_feature_attribute(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<PointFeatureSymbolPacket> Create(std::istream& is);
protected:
size_t MinBlockLength() const override;
size_t MaxBlockLength() const override;
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<PointFeatureSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,46 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class PointGraphicSymbolPacketImpl;
class PointGraphicSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit PointGraphicSymbolPacket();
~PointGraphicSymbolPacket();
PointGraphicSymbolPacket(const PointGraphicSymbolPacket&) = delete;
PointGraphicSymbolPacket&
operator=(const PointGraphicSymbolPacket&) = delete;
PointGraphicSymbolPacket(PointGraphicSymbolPacket&&) noexcept;
PointGraphicSymbolPacket& operator=(PointGraphicSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<PointGraphicSymbolPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<PointGraphicSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,44 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class ScitForecastDataPacketImpl;
class ScitForecastDataPacket : public SpecialGraphicSymbolPacket
{
public:
explicit ScitForecastDataPacket();
~ScitForecastDataPacket();
ScitForecastDataPacket(const ScitForecastDataPacket&) = delete;
ScitForecastDataPacket& operator=(const ScitForecastDataPacket&) = delete;
ScitForecastDataPacket(ScitForecastDataPacket&&) noexcept;
ScitForecastDataPacket& operator=(ScitForecastDataPacket&&) noexcept;
const std::vector<uint8_t>& data() const;
size_t RecordCount() const override;
static std::shared_ptr<ScitForecastDataPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<ScitForecastDataPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,51 @@
#pragma once
#include <scwx/wsr88d/rpg/packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class SpecialGraphicSymbolPacketImpl;
class SpecialGraphicSymbolPacket : public Packet
{
public:
explicit SpecialGraphicSymbolPacket();
~SpecialGraphicSymbolPacket();
SpecialGraphicSymbolPacket(const SpecialGraphicSymbolPacket&) = delete;
SpecialGraphicSymbolPacket&
operator=(const SpecialGraphicSymbolPacket&) = delete;
SpecialGraphicSymbolPacket(SpecialGraphicSymbolPacket&&) noexcept;
SpecialGraphicSymbolPacket& operator=(SpecialGraphicSymbolPacket&&) noexcept;
uint16_t packet_code() const;
uint16_t length_of_block() const;
size_t data_size() const override;
bool Parse(std::istream& is) override;
virtual size_t RecordCount() const = 0;
protected:
virtual size_t MinBlockLength() const;
virtual size_t MaxBlockLength() const;
virtual bool ParseData(std::istream& is) = 0;
private:
std::unique_ptr<SpecialGraphicSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,46 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class StiCircleSymbolPacketImpl;
class StiCircleSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit StiCircleSymbolPacket();
~StiCircleSymbolPacket();
StiCircleSymbolPacket(const StiCircleSymbolPacket&) = delete;
StiCircleSymbolPacket& operator=(const StiCircleSymbolPacket&) = delete;
StiCircleSymbolPacket(StiCircleSymbolPacket&&) noexcept;
StiCircleSymbolPacket& operator=(StiCircleSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
uint16_t radius_of_circle(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<StiCircleSymbolPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<StiCircleSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,46 @@
#pragma once
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <cstdint>
#include <memory>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
class StormIdSymbolPacketImpl;
class StormIdSymbolPacket : public SpecialGraphicSymbolPacket
{
public:
explicit StormIdSymbolPacket();
~StormIdSymbolPacket();
StormIdSymbolPacket(const StormIdSymbolPacket&) = delete;
StormIdSymbolPacket& operator=(const StormIdSymbolPacket&) = delete;
StormIdSymbolPacket(StormIdSymbolPacket&&) noexcept;
StormIdSymbolPacket& operator=(StormIdSymbolPacket&&) noexcept;
int16_t i_position(size_t i) const;
int16_t j_position(size_t i) const;
const std::array<char, 2>& character(size_t i) const;
size_t RecordCount() const override;
static std::shared_ptr<StormIdSymbolPacket> Create(std::istream& is);
protected:
bool ParseData(std::istream& is) override;
private:
std::unique_ptr<StormIdSymbolPacketImpl> p;
};
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,140 @@
#include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::hda_hail_symbol_packet] ";
struct HdaHailSymbol
{
int16_t iPosition_;
int16_t jPosition_;
int16_t probabilityOfHail_;
int16_t probabilityOfSevereHail_;
uint16_t maxHailSize_;
HdaHailSymbol() :
iPosition_ {0},
jPosition_ {0},
probabilityOfHail_ {0},
probabilityOfSevereHail_ {0},
maxHailSize_ {0}
{
}
};
class HdaHailSymbolPacketImpl
{
public:
explicit HdaHailSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~HdaHailSymbolPacketImpl() = default;
std::vector<HdaHailSymbol> symbol_;
size_t recordCount_;
};
HdaHailSymbolPacket::HdaHailSymbolPacket() :
p(std::make_unique<HdaHailSymbolPacketImpl>())
{
}
HdaHailSymbolPacket::~HdaHailSymbolPacket() = default;
HdaHailSymbolPacket::HdaHailSymbolPacket(HdaHailSymbolPacket&&) noexcept =
default;
HdaHailSymbolPacket&
HdaHailSymbolPacket::operator=(HdaHailSymbolPacket&&) noexcept = default;
int16_t HdaHailSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t HdaHailSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
int16_t HdaHailSymbolPacket::probability_of_hail(size_t i) const
{
return p->symbol_[i].probabilityOfHail_;
}
int16_t HdaHailSymbolPacket::probability_of_severe_hail(size_t i) const
{
return p->symbol_[i].probabilityOfSevereHail_;
}
uint16_t HdaHailSymbolPacket::max_hail_size(size_t i) const
{
return p->symbol_[i].maxHailSize_;
}
size_t HdaHailSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool HdaHailSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 19)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 10;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
HdaHailSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.probabilityOfHail_), 2);
is.read(reinterpret_cast<char*>(&s.probabilityOfSevereHail_), 2);
is.read(reinterpret_cast<char*>(&s.maxHailSize_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.probabilityOfHail_ = ntohs(s.probabilityOfHail_);
s.probabilityOfSevereHail_ = ntohs(s.probabilityOfSevereHail_);
s.maxHailSize_ = ntohs(s.maxHailSize_);
}
}
return blockValid;
}
std::shared_ptr<HdaHailSymbolPacket>
HdaHailSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<HdaHailSymbolPacket> packet =
std::make_shared<HdaHailSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,123 @@
#include <scwx/wsr88d/rpg/mesocyclone_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::mesocyclone_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {3, 11};
struct MesocycloneSymbol
{
int16_t iPosition_;
int16_t jPosition_;
int16_t radiusOfMesocyclone_;
MesocycloneSymbol() :
iPosition_ {0}, jPosition_ {0}, radiusOfMesocyclone_ {0}
{
}
};
class MesocycloneSymbolPacketImpl
{
public:
explicit MesocycloneSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~MesocycloneSymbolPacketImpl() = default;
std::vector<MesocycloneSymbol> symbol_;
size_t recordCount_;
};
MesocycloneSymbolPacket::MesocycloneSymbolPacket() :
p(std::make_unique<MesocycloneSymbolPacketImpl>())
{
}
MesocycloneSymbolPacket::~MesocycloneSymbolPacket() = default;
MesocycloneSymbolPacket::MesocycloneSymbolPacket(
MesocycloneSymbolPacket&&) noexcept = default;
MesocycloneSymbolPacket& MesocycloneSymbolPacket::operator=(
MesocycloneSymbolPacket&&) noexcept = default;
int16_t MesocycloneSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t MesocycloneSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
int16_t MesocycloneSymbolPacket::radius_of_mesocyclone(size_t i) const
{
return p->symbol_[i].radiusOfMesocyclone_;
}
size_t MesocycloneSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool MesocycloneSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
MesocycloneSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.radiusOfMesocyclone_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.radiusOfMesocyclone_ = ntohs(s.radiusOfMesocyclone_);
}
}
return blockValid;
}
std::shared_ptr<MesocycloneSymbolPacket>
MesocycloneSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<MesocycloneSymbolPacket> packet =
std::make_shared<MesocycloneSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -2,12 +2,19 @@
#include <scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp> #include <scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp> #include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp> #include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp>
#include <scwx/wsr88d/rpg/linked_vector_packet.hpp> #include <scwx/wsr88d/rpg/linked_vector_packet.hpp>
#include <scwx/wsr88d/rpg/mesocyclone_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/point_feature_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/point_graphic_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/precipitation_rate_data_array_packet.hpp> #include <scwx/wsr88d/rpg/precipitation_rate_data_array_packet.hpp>
#include <scwx/wsr88d/rpg/radial_data_packet.hpp> #include <scwx/wsr88d/rpg/radial_data_packet.hpp>
#include <scwx/wsr88d/rpg/raster_data_packet.hpp> #include <scwx/wsr88d/rpg/raster_data_packet.hpp>
#include <scwx/wsr88d/rpg/scit_forecast_data_packet.hpp>
#include <scwx/wsr88d/rpg/set_color_level_packet.hpp> #include <scwx/wsr88d/rpg/set_color_level_packet.hpp>
#include <scwx/wsr88d/rpg/sti_circle_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/storm_id_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp> #include <scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp>
#include <scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp> #include <scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp>
#include <scwx/wsr88d/rpg/unlinked_vector_packet.hpp> #include <scwx/wsr88d/rpg/unlinked_vector_packet.hpp>
@ -33,6 +40,7 @@ typedef std::function<std::shared_ptr<Packet>(std::istream&)>
static const std::unordered_map<uint16_t, CreateMessageFunction> create_ { static const std::unordered_map<uint16_t, CreateMessageFunction> create_ {
{1, TextAndSpecialSymbolPacket::Create}, {1, TextAndSpecialSymbolPacket::Create},
{2, TextAndSpecialSymbolPacket::Create}, {2, TextAndSpecialSymbolPacket::Create},
{3, MesocycloneSymbolPacket::Create},
{4, WindBarbDataPacket::Create}, {4, WindBarbDataPacket::Create},
{5, VectorArrowDataPacket::Create}, {5, VectorArrowDataPacket::Create},
{6, LinkedVectorPacket::Create}, {6, LinkedVectorPacket::Create},
@ -40,9 +48,20 @@ static const std::unordered_map<uint16_t, CreateMessageFunction> create_ {
{8, TextAndSpecialSymbolPacket::Create}, {8, TextAndSpecialSymbolPacket::Create},
{9, LinkedVectorPacket::Create}, {9, LinkedVectorPacket::Create},
{10, UnlinkedVectorPacket::Create}, {10, UnlinkedVectorPacket::Create},
{11, MesocycloneSymbolPacket::Create},
{12, PointGraphicSymbolPacket::Create},
{13, PointGraphicSymbolPacket::Create},
{14, PointGraphicSymbolPacket::Create},
{15, StormIdSymbolPacket::Create},
{16, DigitalRadialDataArrayPacket::Create}, {16, DigitalRadialDataArrayPacket::Create},
{17, DigitalPrecipitationDataArrayPacket::Create}, {17, DigitalPrecipitationDataArrayPacket::Create},
{18, PrecipitationRateDataArrayPacket::Create}, {18, PrecipitationRateDataArrayPacket::Create},
{19, HdaHailSymbolPacket::Create},
{20, PointFeatureSymbolPacket::Create},
{23, ScitForecastDataPacket::Create},
{24, ScitForecastDataPacket::Create},
{25, StiCircleSymbolPacket::Create},
{26, PointGraphicSymbolPacket::Create},
{0x0802, SetColorLevelPacket::Create}, {0x0802, SetColorLevelPacket::Create},
{0x0E03, LinkedContourVectorPacket::Create}, {0x0E03, LinkedContourVectorPacket::Create},
{0x3501, UnlinkedContourVectorPacket::Create}, {0x3501, UnlinkedContourVectorPacket::Create},

View file

@ -0,0 +1,143 @@
#include <scwx/wsr88d/rpg/point_feature_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::point_feature_symbol_packet] ";
struct PointFeature
{
int16_t iPosition_;
int16_t jPosition_;
uint16_t pointFeatureType_;
uint16_t pointFeatureAttribute_;
PointFeature() :
iPosition_ {0},
jPosition_ {0},
pointFeatureType_ {0},
pointFeatureAttribute_ {0}
{
}
};
class PointFeatureSymbolPacketImpl
{
public:
explicit PointFeatureSymbolPacketImpl() : pointFeature_ {}, recordCount_ {0}
{
}
~PointFeatureSymbolPacketImpl() = default;
std::vector<PointFeature> pointFeature_;
size_t recordCount_;
};
PointFeatureSymbolPacket::PointFeatureSymbolPacket() :
p(std::make_unique<PointFeatureSymbolPacketImpl>())
{
}
PointFeatureSymbolPacket::~PointFeatureSymbolPacket() = default;
PointFeatureSymbolPacket::PointFeatureSymbolPacket(
PointFeatureSymbolPacket&&) noexcept = default;
PointFeatureSymbolPacket& PointFeatureSymbolPacket::operator=(
PointFeatureSymbolPacket&&) noexcept = default;
size_t PointFeatureSymbolPacket::MinBlockLength() const
{
return 8;
}
size_t PointFeatureSymbolPacket::MaxBlockLength() const
{
return 32760;
}
int16_t PointFeatureSymbolPacket::i_position(size_t i) const
{
return p->pointFeature_[i].iPosition_;
}
int16_t PointFeatureSymbolPacket::j_position(size_t i) const
{
return p->pointFeature_[i].jPosition_;
}
uint16_t PointFeatureSymbolPacket::point_feature_type(size_t i) const
{
return p->pointFeature_[i].pointFeatureType_;
}
uint16_t PointFeatureSymbolPacket::point_feature_attribute(size_t i) const
{
return p->pointFeature_[i].pointFeatureAttribute_;
}
size_t PointFeatureSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool PointFeatureSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 20)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 8;
p->pointFeature_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
PointFeature& f = p->pointFeature_[i];
is.read(reinterpret_cast<char*>(&f.iPosition_), 2);
is.read(reinterpret_cast<char*>(&f.jPosition_), 2);
is.read(reinterpret_cast<char*>(&f.pointFeatureType_), 2);
is.read(reinterpret_cast<char*>(&f.pointFeatureAttribute_), 2);
f.iPosition_ = ntohs(f.iPosition_);
f.jPosition_ = ntohs(f.jPosition_);
f.pointFeatureType_ = ntohs(f.pointFeatureType_);
f.pointFeatureAttribute_ = ntohs(f.pointFeatureAttribute_);
}
}
return blockValid;
}
std::shared_ptr<PointFeatureSymbolPacket>
PointFeatureSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<PointFeatureSymbolPacket> packet =
std::make_shared<PointFeatureSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,114 @@
#include <scwx/wsr88d/rpg/point_graphic_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::point_graphic_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {12, 13, 14, 26};
struct PointGraphic
{
int16_t iPosition_;
int16_t jPosition_;
PointGraphic() : iPosition_ {0}, jPosition_ {0} {}
};
class PointGraphicSymbolPacketImpl
{
public:
explicit PointGraphicSymbolPacketImpl() : pointGraphic_ {}, recordCount_ {0}
{
}
~PointGraphicSymbolPacketImpl() = default;
std::vector<PointGraphic> pointGraphic_;
size_t recordCount_;
};
PointGraphicSymbolPacket::PointGraphicSymbolPacket() :
p(std::make_unique<PointGraphicSymbolPacketImpl>())
{
}
PointGraphicSymbolPacket::~PointGraphicSymbolPacket() = default;
PointGraphicSymbolPacket::PointGraphicSymbolPacket(
PointGraphicSymbolPacket&&) noexcept = default;
PointGraphicSymbolPacket& PointGraphicSymbolPacket::operator=(
PointGraphicSymbolPacket&&) noexcept = default;
int16_t PointGraphicSymbolPacket::i_position(size_t i) const
{
return p->pointGraphic_[i].iPosition_;
}
int16_t PointGraphicSymbolPacket::j_position(size_t i) const
{
return p->pointGraphic_[i].jPosition_;
}
size_t PointGraphicSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool PointGraphicSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 4;
p->pointGraphic_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
PointGraphic& f = p->pointGraphic_[i];
is.read(reinterpret_cast<char*>(&f.iPosition_), 2);
is.read(reinterpret_cast<char*>(&f.jPosition_), 2);
f.iPosition_ = ntohs(f.iPosition_);
f.jPosition_ = ntohs(f.jPosition_);
}
}
return blockValid;
}
std::shared_ptr<PointGraphicSymbolPacket>
PointGraphicSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<PointGraphicSymbolPacket> packet =
std::make_shared<PointGraphicSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,89 @@
#include <scwx/wsr88d/rpg/scit_forecast_data_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::scit_forecast_data_packet] ";
static const std::set<uint16_t> packetCodes_ = {23, 24};
class ScitForecastDataPacketImpl
{
public:
explicit ScitForecastDataPacketImpl() : data_ {}, recordCount_ {0} {}
~ScitForecastDataPacketImpl() = default;
std::vector<uint8_t> data_;
size_t recordCount_;
};
ScitForecastDataPacket::ScitForecastDataPacket() :
p(std::make_unique<ScitForecastDataPacketImpl>())
{
}
ScitForecastDataPacket::~ScitForecastDataPacket() = default;
ScitForecastDataPacket::ScitForecastDataPacket(
ScitForecastDataPacket&&) noexcept = default;
ScitForecastDataPacket&
ScitForecastDataPacket::operator=(ScitForecastDataPacket&&) noexcept = default;
const std::vector<uint8_t>& ScitForecastDataPacket::data() const
{
return p->data_;
}
size_t ScitForecastDataPacket::RecordCount() const
{
return p->recordCount_;
}
bool ScitForecastDataPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (!packetCodes_.contains(packet_code()))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block();
p->data_.resize(p->recordCount_);
is.read(reinterpret_cast<char*>(p->data_.data()), p->recordCount_);
}
return blockValid;
}
std::shared_ptr<ScitForecastDataPacket>
ScitForecastDataPacket::Create(std::istream& is)
{
std::shared_ptr<ScitForecastDataPacket> packet =
std::make_shared<ScitForecastDataPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,125 @@
#include <scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp>
#include <istream>
#include <set>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::special_graphic_symbol_packet] ";
static const std::set<uint16_t> packetCodes_ = {
3, 11, 12, 13, 14, 15, 19, 20, 23, 24, 25, 26};
class SpecialGraphicSymbolPacketImpl
{
public:
explicit SpecialGraphicSymbolPacketImpl() :
packetCode_ {0}, lengthOfBlock_ {0}
{
}
~SpecialGraphicSymbolPacketImpl() = default;
uint16_t packetCode_;
uint16_t lengthOfBlock_;
};
SpecialGraphicSymbolPacket::SpecialGraphicSymbolPacket() :
p(std::make_unique<SpecialGraphicSymbolPacketImpl>())
{
}
SpecialGraphicSymbolPacket::~SpecialGraphicSymbolPacket() = default;
SpecialGraphicSymbolPacket::SpecialGraphicSymbolPacket(
SpecialGraphicSymbolPacket&&) noexcept = default;
SpecialGraphicSymbolPacket& SpecialGraphicSymbolPacket::operator=(
SpecialGraphicSymbolPacket&&) noexcept = default;
uint16_t SpecialGraphicSymbolPacket::packet_code() const
{
return p->packetCode_;
}
uint16_t SpecialGraphicSymbolPacket::length_of_block() const
{
return p->lengthOfBlock_;
}
size_t SpecialGraphicSymbolPacket::data_size() const
{
return p->lengthOfBlock_ + 4u;
}
bool SpecialGraphicSymbolPacket::Parse(std::istream& is)
{
bool blockValid = true;
std::streampos isBegin = is.tellg();
is.read(reinterpret_cast<char*>(&p->packetCode_), 2);
is.read(reinterpret_cast<char*>(&p->lengthOfBlock_), 2);
p->packetCode_ = ntohs(p->packetCode_);
p->lengthOfBlock_ = ntohs(p->lengthOfBlock_);
if (is.eof())
{
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
blockValid = false;
}
else
{
const size_t minBlockLength = MinBlockLength();
const size_t maxBlockLength = MaxBlockLength();
if (!packetCodes_.contains(p->packetCode_))
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << p->packetCode_;
blockValid = false;
}
else if (p->lengthOfBlock_ < minBlockLength ||
p->lengthOfBlock_ > maxBlockLength)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid length of block: " << p->packetCode_;
blockValid = false;
}
}
if (blockValid)
{
blockValid = ParseData(is);
}
std::streampos isEnd = is.tellg();
if (!ValidateMessage(is, isEnd - isBegin))
{
blockValid = false;
}
return blockValid;
}
size_t SpecialGraphicSymbolPacket::MinBlockLength() const
{
return 1;
}
size_t SpecialGraphicSymbolPacket::MaxBlockLength() const
{
return 32767;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,117 @@
#include <scwx/wsr88d/rpg/sti_circle_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::sti_circle_symbol_packet] ";
struct StiCircleSymbol
{
int16_t iPosition_;
int16_t jPosition_;
uint16_t radiusOfCircle_;
StiCircleSymbol() : iPosition_ {0}, jPosition_ {0}, radiusOfCircle_ {0} {}
};
class StiCircleSymbolPacketImpl
{
public:
explicit StiCircleSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~StiCircleSymbolPacketImpl() = default;
std::vector<StiCircleSymbol> symbol_;
size_t recordCount_;
};
StiCircleSymbolPacket::StiCircleSymbolPacket() :
p(std::make_unique<StiCircleSymbolPacketImpl>())
{
}
StiCircleSymbolPacket::~StiCircleSymbolPacket() = default;
StiCircleSymbolPacket::StiCircleSymbolPacket(StiCircleSymbolPacket&&) noexcept =
default;
StiCircleSymbolPacket&
StiCircleSymbolPacket::operator=(StiCircleSymbolPacket&&) noexcept = default;
int16_t StiCircleSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t StiCircleSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
uint16_t StiCircleSymbolPacket::radius_of_circle(size_t i) const
{
return p->symbol_[i].radiusOfCircle_;
}
size_t StiCircleSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool StiCircleSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 25)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
StiCircleSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(&s.radiusOfCircle_), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
s.radiusOfCircle_ = ntohs(s.radiusOfCircle_);
}
}
return blockValid;
}
std::shared_ptr<StiCircleSymbolPacket>
StiCircleSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<StiCircleSymbolPacket> packet =
std::make_shared<StiCircleSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -0,0 +1,116 @@
#include <scwx/wsr88d/rpg/storm_id_symbol_packet.hpp>
#include <istream>
#include <string>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace wsr88d
{
namespace rpg
{
static const std::string logPrefix_ =
"[scwx::wsr88d::rpg::storm_id_symbol_packet] ";
struct StormIdSymbol
{
int16_t iPosition_;
int16_t jPosition_;
std::array<char, 2> character_;
StormIdSymbol() : iPosition_ {0}, jPosition_ {0}, character_ {0} {}
};
class StormIdSymbolPacketImpl
{
public:
explicit StormIdSymbolPacketImpl() : symbol_ {}, recordCount_ {0} {}
~StormIdSymbolPacketImpl() = default;
std::vector<StormIdSymbol> symbol_;
size_t recordCount_;
};
StormIdSymbolPacket::StormIdSymbolPacket() :
p(std::make_unique<StormIdSymbolPacketImpl>())
{
}
StormIdSymbolPacket::~StormIdSymbolPacket() = default;
StormIdSymbolPacket::StormIdSymbolPacket(StormIdSymbolPacket&&) noexcept =
default;
StormIdSymbolPacket&
StormIdSymbolPacket::operator=(StormIdSymbolPacket&&) noexcept = default;
int16_t StormIdSymbolPacket::i_position(size_t i) const
{
return p->symbol_[i].iPosition_;
}
int16_t StormIdSymbolPacket::j_position(size_t i) const
{
return p->symbol_[i].jPosition_;
}
const std::array<char, 2>& StormIdSymbolPacket::character(size_t i) const
{
return p->symbol_[i].character_;
}
size_t StormIdSymbolPacket::RecordCount() const
{
return p->recordCount_;
}
bool StormIdSymbolPacket::ParseData(std::istream& is)
{
bool blockValid = true;
if (packet_code() != 15)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid packet code: " << packet_code();
blockValid = false;
}
if (blockValid)
{
p->recordCount_ = length_of_block() / 6;
p->symbol_.resize(p->recordCount_);
for (size_t i = 0; i < p->recordCount_; i++)
{
StormIdSymbol& s = p->symbol_[i];
is.read(reinterpret_cast<char*>(&s.iPosition_), 2);
is.read(reinterpret_cast<char*>(&s.jPosition_), 2);
is.read(reinterpret_cast<char*>(s.character_.data()), 2);
s.iPosition_ = ntohs(s.iPosition_);
s.jPosition_ = ntohs(s.jPosition_);
}
}
return blockValid;
}
std::shared_ptr<StormIdSymbolPacket>
StormIdSymbolPacket::Create(std::istream& is)
{
std::shared_ptr<StormIdSymbolPacket> packet =
std::make_shared<StormIdSymbolPacket>();
if (!packet->Parse(is))
{
packet.reset();
}
return packet;
}
} // namespace rpg
} // namespace wsr88d
} // namespace scwx

View file

@ -48,17 +48,25 @@ set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp
source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp)
set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp
include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp
include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp
include/scwx/wsr88d/rpg/level3_message_header.hpp include/scwx/wsr88d/rpg/level3_message_header.hpp
include/scwx/wsr88d/rpg/linked_contour_vector_packet.hpp include/scwx/wsr88d/rpg/linked_contour_vector_packet.hpp
include/scwx/wsr88d/rpg/linked_vector_packet.hpp include/scwx/wsr88d/rpg/linked_vector_packet.hpp
include/scwx/wsr88d/rpg/mesocyclone_symbol_packet.hpp
include/scwx/wsr88d/rpg/packet.hpp include/scwx/wsr88d/rpg/packet.hpp
include/scwx/wsr88d/rpg/packet_factory.hpp include/scwx/wsr88d/rpg/packet_factory.hpp
include/scwx/wsr88d/rpg/point_feature_symbol_packet.hpp
include/scwx/wsr88d/rpg/point_graphic_symbol_packet.hpp
include/scwx/wsr88d/rpg/precipitation_rate_data_array_packet.hpp include/scwx/wsr88d/rpg/precipitation_rate_data_array_packet.hpp
include/scwx/wsr88d/rpg/product_description_block.hpp include/scwx/wsr88d/rpg/product_description_block.hpp
include/scwx/wsr88d/rpg/product_symbology_block.hpp include/scwx/wsr88d/rpg/product_symbology_block.hpp
include/scwx/wsr88d/rpg/radial_data_packet.hpp include/scwx/wsr88d/rpg/radial_data_packet.hpp
include/scwx/wsr88d/rpg/raster_data_packet.hpp include/scwx/wsr88d/rpg/raster_data_packet.hpp
include/scwx/wsr88d/rpg/scit_forecast_data_packet.hpp
include/scwx/wsr88d/rpg/set_color_level_packet.hpp include/scwx/wsr88d/rpg/set_color_level_packet.hpp
include/scwx/wsr88d/rpg/special_graphic_symbol_packet.hpp
include/scwx/wsr88d/rpg/sti_circle_symbol_packet.hpp
include/scwx/wsr88d/rpg/storm_id_symbol_packet.hpp
include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp
include/scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp include/scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp
include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp
@ -67,17 +75,25 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_pack
include/scwx/wsr88d/rpg/wmo_header.hpp) include/scwx/wsr88d/rpg/wmo_header.hpp)
set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp
source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp
source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp
source/scwx/wsr88d/rpg/level3_message_header.cpp source/scwx/wsr88d/rpg/level3_message_header.cpp
source/scwx/wsr88d/rpg/linked_contour_vector_packet.cpp source/scwx/wsr88d/rpg/linked_contour_vector_packet.cpp
source/scwx/wsr88d/rpg/linked_vector_packet.cpp source/scwx/wsr88d/rpg/linked_vector_packet.cpp
source/scwx/wsr88d/rpg/mesocyclone_symbol_packet.cpp
source/scwx/wsr88d/rpg/packet.cpp source/scwx/wsr88d/rpg/packet.cpp
source/scwx/wsr88d/rpg/packet_factory.cpp source/scwx/wsr88d/rpg/packet_factory.cpp
source/scwx/wsr88d/rpg/point_feature_symbol_packet.cpp
source/scwx/wsr88d/rpg/point_graphic_symbol_packet.cpp
source/scwx/wsr88d/rpg/precipitation_rate_data_array_packet.cpp source/scwx/wsr88d/rpg/precipitation_rate_data_array_packet.cpp
source/scwx/wsr88d/rpg/product_description_block.cpp source/scwx/wsr88d/rpg/product_description_block.cpp
source/scwx/wsr88d/rpg/product_symbology_block.cpp source/scwx/wsr88d/rpg/product_symbology_block.cpp
source/scwx/wsr88d/rpg/radial_data_packet.cpp source/scwx/wsr88d/rpg/radial_data_packet.cpp
source/scwx/wsr88d/rpg/raster_data_packet.cpp source/scwx/wsr88d/rpg/raster_data_packet.cpp
source/scwx/wsr88d/rpg/scit_forecast_data_packet.cpp
source/scwx/wsr88d/rpg/set_color_level_packet.cpp source/scwx/wsr88d/rpg/set_color_level_packet.cpp
source/scwx/wsr88d/rpg/special_graphic_symbol_packet.cpp
source/scwx/wsr88d/rpg/sti_circle_symbol_packet.cpp
source/scwx/wsr88d/rpg/storm_id_symbol_packet.cpp
source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp
source/scwx/wsr88d/rpg/unlinked_contour_vector_packet.cpp source/scwx/wsr88d/rpg/unlinked_contour_vector_packet.cpp
source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp