mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 06:20:06 +00:00 
			
		
		
		
	Draw 4-bit encoded radial data
This commit is contained in:
		
							parent
							
								
									41b491314b
								
							
						
					
					
						commit
						8d1be0f54a
					
				
					 7 changed files with 158 additions and 25 deletions
				
			
		|  | @ -4,6 +4,7 @@ | ||||||
| #include <scwx/util/time.hpp> | #include <scwx/util/time.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/graphic_product_message.hpp> | #include <scwx/wsr88d/rpg/graphic_product_message.hpp> | ||||||
|  | #include <scwx/wsr88d/rpg/radial_data_packet.hpp> | ||||||
| 
 | 
 | ||||||
| #include <boost/log/trivial.hpp> | #include <boost/log/trivial.hpp> | ||||||
| #include <boost/range/irange.hpp> | #include <boost/range/irange.hpp> | ||||||
|  | @ -322,8 +323,10 @@ void Level3RadialView::ComputeSweep() | ||||||
| 
 | 
 | ||||||
|    // A message with radial data should either have a Digital Radial Data Array
 |    // A message with radial data should either have a Digital Radial Data Array
 | ||||||
|    // Packet, or a Radial Data Array Packet (TODO)
 |    // Packet, or a Radial Data Array Packet (TODO)
 | ||||||
|    std::shared_ptr<wsr88d::rpg::DigitalRadialDataArrayPacket> digitalData = |    std::shared_ptr<wsr88d::rpg::DigitalRadialDataArrayPacket> | ||||||
|       nullptr; |                                                   digitalDataPacket = nullptr; | ||||||
|  |    std::shared_ptr<wsr88d::rpg::RadialDataPacket> radialDataPacket  = nullptr; | ||||||
|  |    std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData = nullptr; | ||||||
| 
 | 
 | ||||||
|    for (uint16_t layer = 0; layer < numberOfLayers; layer++) |    for (uint16_t layer = 0; layer < numberOfLayers; layer++) | ||||||
|    { |    { | ||||||
|  | @ -332,40 +335,56 @@ void Level3RadialView::ComputeSweep() | ||||||
| 
 | 
 | ||||||
|       for (auto it = packetList.begin(); it != packetList.end(); it++) |       for (auto it = packetList.begin(); it != packetList.end(); it++) | ||||||
|       { |       { | ||||||
|          digitalData = std::dynamic_pointer_cast< |          // Prefer Digital Radial Data to Radial Data
 | ||||||
|  |          digitalDataPacket = std::dynamic_pointer_cast< | ||||||
|             wsr88d::rpg::DigitalRadialDataArrayPacket>(*it); |             wsr88d::rpg::DigitalRadialDataArrayPacket>(*it); | ||||||
| 
 | 
 | ||||||
|          if (digitalData != nullptr) |          if (digitalDataPacket != nullptr) | ||||||
|  |          { | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          // Otherwise, check for Radial Data
 | ||||||
|  |          if (radialDataPacket == nullptr) | ||||||
|  |          { | ||||||
|  |             radialDataPacket = | ||||||
|  |                std::dynamic_pointer_cast<wsr88d::rpg::RadialDataPacket>(*it); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (digitalDataPacket != nullptr) | ||||||
|       { |       { | ||||||
|          break; |          break; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|       if (digitalData != nullptr) |    if (digitalDataPacket != nullptr) | ||||||
|    { |    { | ||||||
|          break; |       radialData = digitalDataPacket; | ||||||
|    } |    } | ||||||
|    } |    else if (radialDataPacket != nullptr) | ||||||
| 
 |  | ||||||
|    if (digitalData == nullptr) |  | ||||||
|    { |    { | ||||||
|       BOOST_LOG_TRIVIAL(debug) |       radialData = radialDataPacket; | ||||||
|          << logPrefix_ << "No digital radial data array found"; |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "No radial data found"; | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (digitalData->i_center_of_sweep() != 0 || |    // Check if radial data is centered on the radar location
 | ||||||
|        digitalData->j_center_of_sweep() != 0) |    if (radialData->i_center_of_sweep() != 0 || | ||||||
|  |        radialData->j_center_of_sweep() != 0) | ||||||
|    { |    { | ||||||
|       BOOST_LOG_TRIVIAL(warning) |       BOOST_LOG_TRIVIAL(warning) | ||||||
|          << logPrefix_ |          << logPrefix_ | ||||||
|          << "(i, j) is not centered on radar, display is inaccurate: (" |          << "(i, j) is not centered on radar, display is inaccurate: (" | ||||||
|          << digitalData->i_center_of_sweep() << ", " |          << radialData->i_center_of_sweep() << ", " | ||||||
|          << digitalData->j_center_of_sweep() << ")"; |          << radialData->j_center_of_sweep() << ")"; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // Assume the number of radials should be 360 or 720
 |    // Assume the number of radials should be 360 or 720
 | ||||||
|    const size_t radials = digitalData->number_of_radials(); |    const size_t radials = radialData->number_of_radials(); | ||||||
|    if (radials != 360 && radials != 720) |    if (radials != 360 && radials != 720) | ||||||
|    { |    { | ||||||
|       BOOST_LOG_TRIVIAL(warning) |       BOOST_LOG_TRIVIAL(warning) | ||||||
|  | @ -381,7 +400,7 @@ void Level3RadialView::ComputeSweep() | ||||||
|       p->radarProductManager_->coordinates(radialSize); |       p->radarProductManager_->coordinates(radialSize); | ||||||
| 
 | 
 | ||||||
|    // There should be a positive number of range bins in radial data
 |    // There should be a positive number of range bins in radial data
 | ||||||
|    const uint16_t gates = digitalData->number_of_range_bins(); |    const uint16_t gates = radialData->number_of_range_bins(); | ||||||
|    if (gates < 1) |    if (gates < 1) | ||||||
|    { |    { | ||||||
|       BOOST_LOG_TRIVIAL(warning) |       BOOST_LOG_TRIVIAL(warning) | ||||||
|  | @ -419,13 +438,12 @@ void Level3RadialView::ComputeSweep() | ||||||
| 
 | 
 | ||||||
|    // Determine which radial to start at
 |    // Determine which radial to start at
 | ||||||
|    const float    radialMultiplier = radials / 360.0f; |    const float    radialMultiplier = radials / 360.0f; | ||||||
|    const float    startAngle       = digitalData->start_angle(0); |    const float    startAngle       = radialData->start_angle(0); | ||||||
|    const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier); |    const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier); | ||||||
| 
 | 
 | ||||||
|    for (uint16_t radial = 0; radial < digitalData->number_of_radials(); |    for (uint16_t radial = 0; radial < radialData->number_of_radials(); radial++) | ||||||
|         radial++) |  | ||||||
|    { |    { | ||||||
|       const auto dataMomentsArray8 = digitalData->level(radial); |       const auto dataMomentsArray8 = radialData->level(radial); | ||||||
| 
 | 
 | ||||||
|       // Compute gate interval
 |       // Compute gate interval
 | ||||||
|       const uint16_t dataMomentInterval  = descriptionBlock->x_resolution_raw(); |       const uint16_t dataMomentInterval  = descriptionBlock->x_resolution_raw(); | ||||||
|  | @ -449,7 +467,8 @@ void Level3RadialView::ComputeSweep() | ||||||
|          size_t vertexCount = (gate > 0) ? 6 : 3; |          size_t vertexCount = (gate > 0) ? 6 : 3; | ||||||
| 
 | 
 | ||||||
|          // Store data moment value
 |          // Store data moment value
 | ||||||
|          uint8_t dataValue = dataMomentsArray8[i]; |          uint8_t dataValue = | ||||||
|  |             (i < dataMomentsArray8.size()) ? dataMomentsArray8[i] : 0; | ||||||
|          if (dataValue < snrThreshold && dataValue != RANGE_FOLDED) |          if (dataValue < snrThreshold && dataValue != RANGE_FOLDED) | ||||||
|          { |          { | ||||||
|             continue; |             continue; | ||||||
|  | @ -457,7 +476,7 @@ void Level3RadialView::ComputeSweep() | ||||||
| 
 | 
 | ||||||
|          for (size_t m = 0; m < vertexCount; m++) |          for (size_t m = 0; m < vertexCount; m++) | ||||||
|          { |          { | ||||||
|             dataMoments8[mIndex++] = dataMomentsArray8[i]; |             dataMoments8[mIndex++] = dataValue; | ||||||
|          } |          } | ||||||
| 
 | 
 | ||||||
|          // Store vertices
 |          // Store vertices
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rpg/packet.hpp> | #include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp> | ||||||
| 
 | 
 | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <memory> | #include <memory> | ||||||
|  | @ -14,7 +14,7 @@ namespace rpg | ||||||
| 
 | 
 | ||||||
| class DigitalRadialDataArrayPacketImpl; | class DigitalRadialDataArrayPacketImpl; | ||||||
| 
 | 
 | ||||||
| class DigitalRadialDataArrayPacket : public Packet | class DigitalRadialDataArrayPacket : public GenericRadialDataPacket | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit DigitalRadialDataArrayPacket(); |    explicit DigitalRadialDataArrayPacket(); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/wsr88d/rpg/packet.hpp> | ||||||
|  | 
 | ||||||
|  | #include <cstdint> | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class GenericRadialDataPacketImpl; | ||||||
|  | 
 | ||||||
|  | class GenericRadialDataPacket : public Packet | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit GenericRadialDataPacket(); | ||||||
|  |    ~GenericRadialDataPacket(); | ||||||
|  | 
 | ||||||
|  |    GenericRadialDataPacket(const GenericRadialDataPacket&) = delete; | ||||||
|  |    GenericRadialDataPacket& operator=(const GenericRadialDataPacket&) = delete; | ||||||
|  | 
 | ||||||
|  |    GenericRadialDataPacket(GenericRadialDataPacket&&) noexcept; | ||||||
|  |    GenericRadialDataPacket& operator=(GenericRadialDataPacket&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    virtual int16_t  i_center_of_sweep() const     = 0; | ||||||
|  |    virtual int16_t  j_center_of_sweep() const     = 0; | ||||||
|  |    virtual uint16_t number_of_radials() const     = 0; | ||||||
|  |    virtual uint16_t number_of_range_bins() const  = 0; | ||||||
|  |    virtual float    start_angle(uint16_t r) const = 0; | ||||||
|  | 
 | ||||||
|  |    virtual const std::vector<uint8_t>& level(uint16_t r) const = 0; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    std::unique_ptr<GenericRadialDataPacketImpl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace rpg
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rpg/packet.hpp> | #include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp> | ||||||
| 
 | 
 | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <memory> | #include <memory> | ||||||
|  | @ -14,7 +14,7 @@ namespace rpg | ||||||
| 
 | 
 | ||||||
| class RadialDataPacketImpl; | class RadialDataPacketImpl; | ||||||
| 
 | 
 | ||||||
| class RadialDataPacket : public Packet | class RadialDataPacket : public GenericRadialDataPacket | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit RadialDataPacket(); |    explicit RadialDataPacket(); | ||||||
|  | @ -34,6 +34,10 @@ public: | ||||||
|    float    scale_factor() const; |    float    scale_factor() const; | ||||||
|    uint16_t number_of_radials() const; |    uint16_t number_of_radials() const; | ||||||
| 
 | 
 | ||||||
|  |    float                       start_angle(uint16_t r) const; | ||||||
|  |    float                       delta_angle(uint16_t r) const; | ||||||
|  |    const std::vector<uint8_t>& level(uint16_t r) const; | ||||||
|  | 
 | ||||||
|    size_t data_size() const override; |    size_t data_size() const override; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is) override; |    bool Parse(std::istream& is) override; | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								wxdata/source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								wxdata/source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | #include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp> | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <boost/log/trivial.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = | ||||||
|  |    "[scwx::wsr88d::rpg::generic_radial_data_packet] "; | ||||||
|  | 
 | ||||||
|  | class GenericRadialDataPacketImpl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit GenericRadialDataPacketImpl() = default; | ||||||
|  |    ~GenericRadialDataPacketImpl()         = default; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | GenericRadialDataPacket::GenericRadialDataPacket() : | ||||||
|  |     p(std::make_unique<GenericRadialDataPacketImpl>()) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | GenericRadialDataPacket::~GenericRadialDataPacket() = default; | ||||||
|  | 
 | ||||||
|  | GenericRadialDataPacket::GenericRadialDataPacket( | ||||||
|  |    GenericRadialDataPacket&&) noexcept                    = default; | ||||||
|  | GenericRadialDataPacket& GenericRadialDataPacket::operator=( | ||||||
|  |    GenericRadialDataPacket&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | } // namespace rpg
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -24,9 +24,14 @@ public: | ||||||
|       uint16_t             startAngle_; |       uint16_t             startAngle_; | ||||||
|       uint16_t             angleDelta_; |       uint16_t             angleDelta_; | ||||||
|       std::vector<uint8_t> data_; |       std::vector<uint8_t> data_; | ||||||
|  |       std::vector<uint8_t> level_; | ||||||
| 
 | 
 | ||||||
|       Radial() : |       Radial() : | ||||||
|           numberOfRleHalfwords_ {0}, startAngle_ {0}, angleDelta_ {0}, data_ {} |           numberOfRleHalfwords_ {0}, | ||||||
|  |           startAngle_ {0}, | ||||||
|  |           angleDelta_ {0}, | ||||||
|  |           data_ {}, | ||||||
|  |           level_ {} | ||||||
|       { |       { | ||||||
|       } |       } | ||||||
|    }; |    }; | ||||||
|  | @ -103,6 +108,21 @@ uint16_t RadialDataPacket::number_of_radials() const | ||||||
|    return p->numberOfRadials_; |    return p->numberOfRadials_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | float RadialDataPacket::start_angle(uint16_t r) const | ||||||
|  | { | ||||||
|  |    return p->radial_[r].startAngle_ * 0.1f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | float RadialDataPacket::delta_angle(uint16_t r) const | ||||||
|  | { | ||||||
|  |    return p->radial_[r].angleDelta_ * 0.1f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const std::vector<uint8_t>& RadialDataPacket::level(uint16_t r) const | ||||||
|  | { | ||||||
|  |    return p->radial_[r].level_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| size_t RadialDataPacket::data_size() const | size_t RadialDataPacket::data_size() const | ||||||
| { | { | ||||||
|    return p->dataSize_; |    return p->dataSize_; | ||||||
|  | @ -197,6 +217,14 @@ bool RadialDataPacket::Parse(std::istream& is) | ||||||
|          { |          { | ||||||
|             radial.data_.pop_back(); |             radial.data_.pop_back(); | ||||||
|          } |          } | ||||||
|  | 
 | ||||||
|  |          radial.level_.resize(radial.data_.size()); | ||||||
|  | 
 | ||||||
|  |          std::transform(std::execution::par_unseq, | ||||||
|  |                         radial.data_.cbegin(), | ||||||
|  |                         radial.data_.cend(), | ||||||
|  |                         radial.level_.begin(), | ||||||
|  |                         [](uint8_t data) -> uint8_t { return data & 0x0f; }); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -80,6 +80,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.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/general_status_message.hpp |                    include/scwx/wsr88d/rpg/general_status_message.hpp | ||||||
|                    include/scwx/wsr88d/rpg/generic_data_packet.hpp |                    include/scwx/wsr88d/rpg/generic_data_packet.hpp | ||||||
|  |                    include/scwx/wsr88d/rpg/generic_radial_data_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/graphic_alphanumeric_block.hpp |                    include/scwx/wsr88d/rpg/graphic_alphanumeric_block.hpp | ||||||
|                    include/scwx/wsr88d/rpg/graphic_product_message.hpp |                    include/scwx/wsr88d/rpg/graphic_product_message.hpp | ||||||
|                    include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp |                    include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp | ||||||
|  | @ -118,6 +119,7 @@ set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.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/general_status_message.cpp |                    source/scwx/wsr88d/rpg/general_status_message.cpp | ||||||
|                    source/scwx/wsr88d/rpg/generic_data_packet.cpp |                    source/scwx/wsr88d/rpg/generic_data_packet.cpp | ||||||
|  |                    source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/graphic_alphanumeric_block.cpp |                    source/scwx/wsr88d/rpg/graphic_alphanumeric_block.cpp | ||||||
|                    source/scwx/wsr88d/rpg/graphic_product_message.cpp |                    source/scwx/wsr88d/rpg/graphic_product_message.cpp | ||||||
|                    source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp |                    source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat