mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 01:40:05 +00:00
Update RPG to Build 23.0
This commit is contained in:
parent
ef7caf5519
commit
e49adafda9
6 changed files with 299 additions and 24 deletions
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/wsr88d/rpg/packet.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace scwx::wsr88d::rpg
|
||||
{
|
||||
|
||||
class DigitalRasterDataArrayPacket : public Packet
|
||||
{
|
||||
public:
|
||||
explicit DigitalRasterDataArrayPacket();
|
||||
~DigitalRasterDataArrayPacket();
|
||||
|
||||
DigitalRasterDataArrayPacket(const DigitalRasterDataArrayPacket&) = delete;
|
||||
DigitalRasterDataArrayPacket&
|
||||
operator=(const DigitalRasterDataArrayPacket&) = delete;
|
||||
|
||||
DigitalRasterDataArrayPacket(DigitalRasterDataArrayPacket&&) noexcept;
|
||||
DigitalRasterDataArrayPacket&
|
||||
operator=(DigitalRasterDataArrayPacket&&) noexcept;
|
||||
|
||||
[[nodiscard]] std::uint16_t packet_code() const override;
|
||||
[[nodiscard]] std::uint16_t i_coordinate_start() const;
|
||||
[[nodiscard]] std::uint16_t j_coordinate_start() const;
|
||||
[[nodiscard]] std::uint16_t i_scale_factor() const;
|
||||
[[nodiscard]] std::uint16_t j_scale_factor() const;
|
||||
[[nodiscard]] std::uint16_t number_of_cells() const;
|
||||
[[nodiscard]] std::uint16_t number_of_rows() const;
|
||||
|
||||
[[nodiscard]] std::uint16_t number_of_bytes_in_row(std::uint16_t r) const;
|
||||
[[nodiscard]] const std::vector<std::uint8_t>& level(std::uint16_t r) const;
|
||||
|
||||
[[nodiscard]] std::size_t data_size() const override;
|
||||
|
||||
bool Parse(std::istream& is) override;
|
||||
|
||||
static std::shared_ptr<DigitalRasterDataArrayPacket>
|
||||
Create(std::istream& is);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace scwx::wsr88d::rpg
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
#include <scwx/wsr88d/rpg/digital_raster_data_array_packet.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <istream>
|
||||
#include <string>
|
||||
|
||||
namespace scwx::wsr88d::rpg
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ =
|
||||
"scwx::wsr88d::rpg::digital_raster_data_array_packet";
|
||||
static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||
|
||||
class DigitalRasterDataArrayPacket::Impl
|
||||
{
|
||||
public:
|
||||
struct Row
|
||||
{
|
||||
std::uint16_t numberOfBytes_ {0};
|
||||
std::vector<std::uint8_t> level_ {};
|
||||
};
|
||||
|
||||
explicit Impl() = default;
|
||||
~Impl() = default;
|
||||
|
||||
Impl(const Impl&) = delete;
|
||||
Impl& operator=(const Impl&) = delete;
|
||||
Impl(const Impl&&) = delete;
|
||||
Impl& operator=(const Impl&&) = delete;
|
||||
|
||||
std::uint16_t packetCode_ {0};
|
||||
std::uint16_t iCoordinateStart_ {0};
|
||||
std::uint16_t jCoordinateStart_ {0};
|
||||
std::uint16_t iScaleFactor_ {0};
|
||||
std::uint16_t jScaleFactor_ {0};
|
||||
std::uint16_t numberOfCells_ {0};
|
||||
std::uint16_t numberOfRows_ {0};
|
||||
std::uint16_t numberOfBytesInRow_ {0};
|
||||
|
||||
// Repeat for each row
|
||||
std::vector<Row> row_ {};
|
||||
|
||||
std::size_t dataSize_ {0};
|
||||
};
|
||||
|
||||
DigitalRasterDataArrayPacket::DigitalRasterDataArrayPacket() :
|
||||
p(std::make_unique<Impl>())
|
||||
{
|
||||
}
|
||||
DigitalRasterDataArrayPacket::~DigitalRasterDataArrayPacket() = default;
|
||||
|
||||
DigitalRasterDataArrayPacket::DigitalRasterDataArrayPacket(
|
||||
DigitalRasterDataArrayPacket&&) noexcept = default;
|
||||
DigitalRasterDataArrayPacket& DigitalRasterDataArrayPacket::operator=(
|
||||
DigitalRasterDataArrayPacket&&) noexcept = default;
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::packet_code() const
|
||||
{
|
||||
return p->packetCode_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::i_coordinate_start() const
|
||||
{
|
||||
return p->iCoordinateStart_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::j_coordinate_start() const
|
||||
{
|
||||
return p->jCoordinateStart_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::i_scale_factor() const
|
||||
{
|
||||
return p->iScaleFactor_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::j_scale_factor() const
|
||||
{
|
||||
return p->jScaleFactor_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::number_of_cells() const
|
||||
{
|
||||
return p->numberOfCells_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRasterDataArrayPacket::number_of_rows() const
|
||||
{
|
||||
return p->numberOfRows_;
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
DigitalRasterDataArrayPacket::number_of_bytes_in_row(std::uint16_t r) const
|
||||
{
|
||||
return p->row_[r].numberOfBytes_;
|
||||
}
|
||||
|
||||
const std::vector<std::uint8_t>&
|
||||
DigitalRasterDataArrayPacket::level(std::uint16_t r) const
|
||||
{
|
||||
return p->row_[r].level_;
|
||||
}
|
||||
|
||||
bool DigitalRasterDataArrayPacket::Parse(std::istream& is)
|
||||
{
|
||||
bool blockValid = true;
|
||||
std::size_t bytesRead = 0;
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
is.read(reinterpret_cast<char*>(&p->packetCode_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->iCoordinateStart_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->jCoordinateStart_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->iScaleFactor_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->jScaleFactor_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->numberOfCells_), 2);
|
||||
is.read(reinterpret_cast<char*>(&p->numberOfRows_), 2);
|
||||
bytesRead += 14;
|
||||
|
||||
p->packetCode_ = ntohs(p->packetCode_);
|
||||
p->iCoordinateStart_ = ntohs(p->iCoordinateStart_);
|
||||
p->jCoordinateStart_ = ntohs(p->jCoordinateStart_);
|
||||
p->iScaleFactor_ = ntohs(p->iScaleFactor_);
|
||||
p->jScaleFactor_ = ntohs(p->jScaleFactor_);
|
||||
p->numberOfCells_ = ntohs(p->numberOfCells_);
|
||||
p->numberOfRows_ = ntohs(p->numberOfRows_);
|
||||
|
||||
if (is.eof())
|
||||
{
|
||||
logger_->debug("Reached end of file");
|
||||
blockValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->packetCode_ != 33)
|
||||
{
|
||||
logger_->warn("Invalid packet code: {}", p->packetCode_);
|
||||
blockValid = false;
|
||||
}
|
||||
if (p->numberOfCells_ < 1 || p->numberOfCells_ > 1840)
|
||||
{
|
||||
logger_->warn("Invalid number of cells: {}", p->numberOfCells_);
|
||||
blockValid = false;
|
||||
}
|
||||
if (p->numberOfRows_ < 1 || p->numberOfRows_ > 464)
|
||||
{
|
||||
logger_->warn("Invalid number of rows: {}", p->numberOfRows_);
|
||||
blockValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (blockValid)
|
||||
{
|
||||
p->row_.resize(p->numberOfRows_);
|
||||
|
||||
for (std::uint16_t r = 0; r < p->numberOfRows_; r++)
|
||||
{
|
||||
auto& row = p->row_[r];
|
||||
|
||||
is.read(reinterpret_cast<char*>(&row.numberOfBytes_), 2);
|
||||
bytesRead += 2;
|
||||
|
||||
row.numberOfBytes_ = ntohs(row.numberOfBytes_);
|
||||
|
||||
if (row.numberOfBytes_ < 1 || row.numberOfBytes_ > 1840)
|
||||
{
|
||||
logger_->warn(
|
||||
"Invalid number of bytes: {} (Row {})", row.numberOfBytes_, r);
|
||||
blockValid = false;
|
||||
break;
|
||||
}
|
||||
else if (row.numberOfBytes_ < p->numberOfCells_)
|
||||
{
|
||||
logger_->warn("Number of bytes < number of cells: {} < {} (Row {})",
|
||||
row.numberOfBytes_,
|
||||
p->numberOfCells_,
|
||||
r);
|
||||
blockValid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Read raster bins
|
||||
std::size_t dataSize = p->numberOfCells_;
|
||||
row.level_.resize(dataSize);
|
||||
is.read(reinterpret_cast<char*>(row.level_.data()),
|
||||
static_cast<std::streamsize>(dataSize));
|
||||
|
||||
is.seekg(static_cast<std::streamoff>(row.numberOfBytes_ - dataSize),
|
||||
std::ios_base::cur);
|
||||
bytesRead += row.numberOfBytes_;
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
p->dataSize_ = bytesRead;
|
||||
|
||||
if (!ValidateMessage(is, bytesRead))
|
||||
{
|
||||
blockValid = false;
|
||||
}
|
||||
|
||||
return blockValid;
|
||||
}
|
||||
|
||||
std::shared_ptr<DigitalRasterDataArrayPacket>
|
||||
DigitalRasterDataArrayPacket::Create(std::istream& is)
|
||||
{
|
||||
std::shared_ptr<DigitalRasterDataArrayPacket> packet =
|
||||
std::make_shared<DigitalRasterDataArrayPacket>();
|
||||
|
||||
if (!packet->Parse(is))
|
||||
{
|
||||
packet.reset();
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
} // namespace scwx::wsr88d::rpg
|
||||
|
|
@ -119,9 +119,14 @@ static const std::unordered_map<int, CreateLevel3MessageFunction> //
|
|||
{182, GraphicProductMessage::Create},
|
||||
{184, GraphicProductMessage::Create},
|
||||
{186, GraphicProductMessage::Create},
|
||||
{189, GraphicProductMessage::Create},
|
||||
{190, GraphicProductMessage::Create},
|
||||
{191, GraphicProductMessage::Create},
|
||||
{192, GraphicProductMessage::Create},
|
||||
{193, GraphicProductMessage::Create},
|
||||
{195, GraphicProductMessage::Create},
|
||||
{196, GraphicProductMessage::Create},
|
||||
{197, GraphicProductMessage::Create},
|
||||
{202, GraphicProductMessage::Create}};
|
||||
|
||||
std::shared_ptr<Level3Message> Level3MessageFactory::Create(std::istream& is)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <scwx/wsr88d/rpg/cell_trend_volume_scan_times.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_raster_data_array_packet.hpp>
|
||||
#include <scwx/wsr88d/rpg/generic_data_packet.hpp>
|
||||
#include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp>
|
||||
#include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp>
|
||||
|
|
@ -69,6 +70,7 @@ static const std::unordered_map<unsigned int, CreateMessageFunction> create_ {
|
|||
{26, PointGraphicSymbolPacket::Create},
|
||||
{28, GenericDataPacket::Create},
|
||||
{29, GenericDataPacket::Create},
|
||||
{33, DigitalRasterDataArrayPacket::Create},
|
||||
{0x0802, SetColorLevelPacket::Create},
|
||||
{0x0E03, LinkedContourVectorPacket::Create},
|
||||
{0x3501, UnlinkedContourVectorPacket::Create},
|
||||
|
|
|
|||
|
|
@ -21,28 +21,13 @@ static const std::string logPrefix_ =
|
|||
static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||
|
||||
static const std::set<int> compressedProducts_ = {
|
||||
32, 94, 99, 134, 135, 138, 149, 152, 153, 154, 155,
|
||||
159, 161, 163, 165, 167, 168, 170, 172, 173, 174, 175,
|
||||
176, 177, 178, 179, 180, 182, 186, 193, 195, 202};
|
||||
32, 94, 99, 113, 134, 135, 138, 149, 152, 153, 154, 155, 159,
|
||||
161, 163, 165, 167, 168, 170, 172, 173, 174, 175, 176, 177, 178,
|
||||
179, 180, 182, 186, 189, 190, 191, 192, 193, 195, 197, 202};
|
||||
|
||||
static const std::set<int> uncodedDataLevelProducts_ = {32,
|
||||
34,
|
||||
81,
|
||||
93,
|
||||
94,
|
||||
99,
|
||||
134,
|
||||
135,
|
||||
138,
|
||||
153,
|
||||
154,
|
||||
155,
|
||||
159,
|
||||
161,
|
||||
163,
|
||||
177,
|
||||
193,
|
||||
195};
|
||||
static const std::set<int> uncodedDataLevelProducts_ = {
|
||||
32, 34, 81, 93, 94, 99, 134, 135, 138, 153, 154, 155,
|
||||
159, 161, 163, 177, 189, 190, 191, 192, 193, 195, 197};
|
||||
|
||||
static const std::unordered_map<int, unsigned int> rangeMap_ {
|
||||
{19, 230}, {20, 460}, {27, 230}, {30, 230}, {31, 230}, {32, 230},
|
||||
|
|
@ -57,7 +42,8 @@ static const std::unordered_map<int, unsigned int> rangeMap_ {
|
|||
{163, 300}, {165, 300}, {166, 230}, {167, 300}, {168, 300}, {169, 230},
|
||||
{170, 230}, {171, 230}, {172, 230}, {173, 230}, {174, 230}, {175, 230},
|
||||
{176, 230}, {177, 230}, {178, 300}, {179, 300}, {180, 89}, {181, 89},
|
||||
{182, 89}, {184, 89}, {186, 417}, {193, 460}, {195, 460}, {196, 50}};
|
||||
{182, 89}, {184, 89}, {186, 417}, {193, 460}, {195, 460}, {196, 50},
|
||||
{197, 230}};
|
||||
|
||||
static const std::unordered_map<int, unsigned int> xResolutionMap_ {
|
||||
{19, 1000}, {20, 2000}, {27, 1000}, {30, 1000}, {31, 2000}, {32, 1000},
|
||||
|
|
@ -71,7 +57,7 @@ static const std::unordered_map<int, unsigned int> xResolutionMap_ {
|
|||
{166, 250}, {167, 250}, {168, 250}, {169, 2000}, {170, 250}, {171, 2000},
|
||||
{172, 250}, {173, 250}, {174, 250}, {175, 250}, {176, 250}, {177, 250},
|
||||
{178, 1000}, {179, 1000}, {180, 150}, {181, 150}, {182, 150}, {184, 150},
|
||||
{186, 300}, {193, 250}, {195, 1000}};
|
||||
{186, 300}, {193, 250}, {195, 1000}, {197, 250}};
|
||||
|
||||
static const std::unordered_map<int, unsigned int> yResolutionMap_ {{37, 1000},
|
||||
{38, 4000},
|
||||
|
|
@ -86,7 +72,11 @@ static const std::unordered_map<int, unsigned int> yResolutionMap_ {{37, 1000},
|
|||
{90, 4000},
|
||||
{97, 1000},
|
||||
{98, 4000},
|
||||
{166, 250}};
|
||||
{166, 250},
|
||||
{189, 20},
|
||||
{190, 20},
|
||||
{191, 20},
|
||||
{192, 20}};
|
||||
|
||||
// GR uses different internal units than defined units in level 3 products
|
||||
static const std::unordered_map<std::int16_t, float> grScale_ {
|
||||
|
|
@ -580,6 +570,10 @@ uint16_t ProductDescriptionBlock::number_of_levels() const
|
|||
break;
|
||||
|
||||
case 134:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
numberOfLevels = 256;
|
||||
break;
|
||||
|
||||
|
|
@ -864,6 +858,10 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const
|
|||
case 163:
|
||||
case 167:
|
||||
case 168:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
case 195:
|
||||
switch (level)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp
|
|||
include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.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_raster_data_array_packet.hpp
|
||||
include/scwx/wsr88d/rpg/general_status_message.hpp
|
||||
include/scwx/wsr88d/rpg/generic_data_packet.hpp
|
||||
include/scwx/wsr88d/rpg/generic_radial_data_packet.hpp
|
||||
|
|
@ -188,6 +189,7 @@ set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.cpp
|
|||
source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp
|
||||
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_raster_data_array_packet.cpp
|
||||
source/scwx/wsr88d/rpg/general_status_message.cpp
|
||||
source/scwx/wsr88d/rpg/generic_data_packet.cpp
|
||||
source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue