mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 07:10: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,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) | ||||
|       { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat