From 5dcf65b79ca64913fe88a99affb0e62c82d10a7e Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 8 Jan 2022 22:18:36 -0600 Subject: [PATCH] Vector arrow data packet --- .../wsr88d/rpg/vector_arrow_data_packet.hpp | 44 +++++ .../source/scwx/wsr88d/rpg/packet_factory.cpp | 2 + .../wsr88d/rpg/vector_arrow_data_packet.cpp | 153 ++++++++++++++++++ wxdata/wxdata.cmake | 2 + 4 files changed, 201 insertions(+) create mode 100644 wxdata/include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/vector_arrow_data_packet.cpp diff --git a/wxdata/include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp new file mode 100644 index 00000000..57464fcb --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class VectorArrowDataPacketImpl; + +class VectorArrowDataPacket : public Packet +{ +public: + explicit VectorArrowDataPacket(); + ~VectorArrowDataPacket(); + + VectorArrowDataPacket(const VectorArrowDataPacket&) = delete; + VectorArrowDataPacket& operator=(const VectorArrowDataPacket&) = delete; + + VectorArrowDataPacket(VectorArrowDataPacket&&) noexcept; + VectorArrowDataPacket& operator=(VectorArrowDataPacket&&) noexcept; + + uint16_t packet_code() const; + uint16_t length_of_block() const; + + size_t data_size() const override; + + bool Parse(std::istream& is) override; + + static std::shared_ptr Create(std::istream& is); + +private: + std::unique_ptr p; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp b/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp index 3e525e57..ca006570 100644 --- a/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/packet_factory.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -31,6 +32,7 @@ typedef std::function(std::istream&)> static const std::unordered_map create_ { {1, TextAndSpecialSymbolPacket::Create}, {2, TextAndSpecialSymbolPacket::Create}, + {5, VectorArrowDataPacket::Create}, {6, LinkedVectorPacket::Create}, {7, UnlinkedVectorPacket::Create}, {8, TextAndSpecialSymbolPacket::Create}, diff --git a/wxdata/source/scwx/wsr88d/rpg/vector_arrow_data_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/vector_arrow_data_packet.cpp new file mode 100644 index 00000000..277a6660 --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/vector_arrow_data_packet.cpp @@ -0,0 +1,153 @@ +#include + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::vector_arrow_data_packet] "; + +struct VectorArrow +{ + int16_t iCoordinatePoint_; + int16_t jCoordinatePoint_; + uint16_t directionOfArrow_; + uint16_t arrowLength_; + uint16_t arrowHeadLength_; + + VectorArrow() : + iCoordinatePoint_ {0}, + jCoordinatePoint_ {0}, + directionOfArrow_ {0}, + arrowLength_ {0}, + arrowHeadLength_ {0} + { + } +}; + +class VectorArrowDataPacketImpl +{ +public: + explicit VectorArrowDataPacketImpl() : + packetCode_ {0}, lengthOfBlock_ {0}, arrow_ {} + { + } + ~VectorArrowDataPacketImpl() = default; + + uint16_t packetCode_; + uint16_t lengthOfBlock_; + + std::vector arrow_; +}; + +VectorArrowDataPacket::VectorArrowDataPacket() : + p(std::make_unique()) +{ +} +VectorArrowDataPacket::~VectorArrowDataPacket() = default; + +VectorArrowDataPacket::VectorArrowDataPacket(VectorArrowDataPacket&&) noexcept = + default; +VectorArrowDataPacket& +VectorArrowDataPacket::operator=(VectorArrowDataPacket&&) noexcept = default; + +uint16_t VectorArrowDataPacket::packet_code() const +{ + return p->packetCode_; +} + +uint16_t VectorArrowDataPacket::length_of_block() const +{ + return p->lengthOfBlock_; +} + +size_t VectorArrowDataPacket::data_size() const +{ + return p->lengthOfBlock_ + 4u; +} + +bool VectorArrowDataPacket::Parse(std::istream& is) +{ + bool blockValid = true; + + std::streampos isBegin = is.tellg(); + + is.read(reinterpret_cast(&p->packetCode_), 2); + is.read(reinterpret_cast(&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 + { + if (p->packetCode_ != 5) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + } + + // The number of vectors is equal to the size divided by the number of bytes + // in a vector + size_t vectorCount = p->lengthOfBlock_ / 10; + + p->arrow_.resize(vectorCount); + + for (int v = 0; v < vectorCount && !is.eof(); v++) + { + VectorArrow& arrow = p->arrow_[v]; + + is.read(reinterpret_cast(&arrow.iCoordinatePoint_), 2); + is.read(reinterpret_cast(&arrow.jCoordinatePoint_), 2); + is.read(reinterpret_cast(&arrow.directionOfArrow_), 2); + is.read(reinterpret_cast(&arrow.arrowLength_), 2); + is.read(reinterpret_cast(&arrow.arrowHeadLength_), 2); + + arrow.iCoordinatePoint_ = ntohs(arrow.iCoordinatePoint_); + arrow.jCoordinatePoint_ = ntohs(arrow.jCoordinatePoint_); + arrow.directionOfArrow_ = ntohs(arrow.directionOfArrow_); + arrow.arrowLength_ = ntohs(arrow.arrowLength_); + arrow.arrowHeadLength_ = ntohs(arrow.arrowHeadLength_); + } + + std::streampos isEnd = is.tellg(); + + if (!ValidateMessage(is, isEnd - isBegin)) + { + blockValid = false; + } + + return blockValid; +} + +std::shared_ptr +VectorArrowDataPacket::Create(std::istream& is) +{ + std::shared_ptr packet = + std::make_shared(); + + if (!packet->Parse(is)) + { + packet.reset(); + } + + return packet; +} + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 9bb95cce..4495b55e 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -62,6 +62,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/digital_precipitation_data_array_pack include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp include/scwx/wsr88d/rpg/unlinked_contour_vector_packet.hpp include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp + include/scwx/wsr88d/rpg/vector_arrow_data_packet.hpp include/scwx/wsr88d/rpg/wmo_header.hpp) set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp @@ -79,6 +80,7 @@ set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/digital_precipitation_data_array_packe source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp source/scwx/wsr88d/rpg/unlinked_contour_vector_packet.cpp source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp + source/scwx/wsr88d/rpg/vector_arrow_data_packet.cpp source/scwx/wsr88d/rpg/wmo_header.cpp) add_library(wxdata OBJECT ${HDR_COMMON}