mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:00:04 +00:00 
			
		
		
		
	Clutter filter bypass map
This commit is contained in:
		
							parent
							
								
									0df6defe01
								
							
						
					
					
						commit
						8f362cc881
					
				
					 4 changed files with 208 additions and 2 deletions
				
			
		
							
								
								
									
										46
									
								
								wxdata/include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								wxdata/include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rda | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class ClutterFilterBypassMapImpl; | ||||||
|  | 
 | ||||||
|  | class ClutterFilterBypassMap : public Level2Message | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit ClutterFilterBypassMap(); | ||||||
|  |    ~ClutterFilterBypassMap(); | ||||||
|  | 
 | ||||||
|  |    ClutterFilterBypassMap(const ClutterFilterBypassMap&) = delete; | ||||||
|  |    ClutterFilterBypassMap& operator=(const ClutterFilterBypassMap&) = delete; | ||||||
|  | 
 | ||||||
|  |    ClutterFilterBypassMap(ClutterFilterBypassMap&&) noexcept; | ||||||
|  |    ClutterFilterBypassMap& operator=(ClutterFilterBypassMap&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    uint16_t map_generation_date() const; | ||||||
|  |    uint16_t map_generation_time() const; | ||||||
|  |    uint16_t number_of_elevation_segments() const; | ||||||
|  |    uint16_t range_bin(uint16_t e, uint16_t r, uint16_t b) const; | ||||||
|  | 
 | ||||||
|  |    bool Parse(std::istream& is); | ||||||
|  | 
 | ||||||
|  |    static std::shared_ptr<ClutterFilterBypassMap> | ||||||
|  |    Create(Level2MessageHeader&& header, std::istream& is); | ||||||
|  | 
 | ||||||
|  |    static constexpr size_t NUM_RADIALS          = 360u; | ||||||
|  |    static constexpr size_t NUM_RANGE_BINS       = 512u; | ||||||
|  |    static constexpr size_t NUM_CODED_RANGE_BINS = NUM_RANGE_BINS / 16u; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    std::unique_ptr<ClutterFilterBypassMapImpl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace rda
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										156
									
								
								wxdata/source/scwx/wsr88d/rda/clutter_filter_bypass_map.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								wxdata/source/scwx/wsr88d/rda/clutter_filter_bypass_map.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,156 @@ | ||||||
|  | #include <scwx/wsr88d/rda/clutter_filter_bypass_map.hpp> | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <boost/log/trivial.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace wsr88d | ||||||
|  | { | ||||||
|  | namespace rda | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = | ||||||
|  |    "[scwx::wsr88d::rda::clutter_filter_bypass_map] "; | ||||||
|  | 
 | ||||||
|  | class ClutterFilterBypassMapImpl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit ClutterFilterBypassMapImpl() : | ||||||
|  |        mapGenerationDate_(), mapGenerationTime_(), rangeBins_() {}; | ||||||
|  |    ~ClutterFilterBypassMapImpl() = default; | ||||||
|  | 
 | ||||||
|  |    uint16_t mapGenerationDate_; | ||||||
|  |    uint16_t mapGenerationTime_; | ||||||
|  | 
 | ||||||
|  |    std::vector<std::vector<std::vector<uint16_t>>> rangeBins_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ClutterFilterBypassMap::ClutterFilterBypassMap() : | ||||||
|  |     Level2Message(), p(std::make_unique<ClutterFilterBypassMapImpl>()) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | ClutterFilterBypassMap::~ClutterFilterBypassMap() = default; | ||||||
|  | 
 | ||||||
|  | ClutterFilterBypassMap::ClutterFilterBypassMap( | ||||||
|  |    ClutterFilterBypassMap&&) noexcept = default; | ||||||
|  | ClutterFilterBypassMap& | ||||||
|  | ClutterFilterBypassMap::operator=(ClutterFilterBypassMap&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | uint16_t ClutterFilterBypassMap::map_generation_date() const | ||||||
|  | { | ||||||
|  |    return p->mapGenerationDate_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t ClutterFilterBypassMap::map_generation_time() const | ||||||
|  | { | ||||||
|  |    return p->mapGenerationTime_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t ClutterFilterBypassMap::number_of_elevation_segments() const | ||||||
|  | { | ||||||
|  |    return static_cast<uint16_t>(p->rangeBins_.size()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t | ||||||
|  | ClutterFilterBypassMap::range_bin(uint16_t e, uint16_t r, uint16_t b) const | ||||||
|  | { | ||||||
|  |    return p->rangeBins_[e][r][b]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool ClutterFilterBypassMap::Parse(std::istream& is) | ||||||
|  | { | ||||||
|  |    BOOST_LOG_TRIVIAL(trace) | ||||||
|  |       << logPrefix_ << "Parsing Clutter Filter Bypass Map (Message Type 13)"; | ||||||
|  | 
 | ||||||
|  |    bool     messageValid         = true; | ||||||
|  |    size_t   bytesRead            = 0; | ||||||
|  |    uint16_t numElevationSegments = 0; | ||||||
|  | 
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->mapGenerationDate_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->mapGenerationTime_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&numElevationSegments), 2); | ||||||
|  |    bytesRead += 6; | ||||||
|  | 
 | ||||||
|  |    p->mapGenerationDate_ = ntohs(p->mapGenerationDate_); | ||||||
|  |    p->mapGenerationTime_ = ntohs(p->mapGenerationTime_); | ||||||
|  |    numElevationSegments  = ntohs(numElevationSegments); | ||||||
|  | 
 | ||||||
|  |    if (p->mapGenerationDate_ < 1) | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(warning) | ||||||
|  |          << logPrefix_ << "Invalid date: " << p->mapGenerationDate_; | ||||||
|  |       messageValid = false; | ||||||
|  |    } | ||||||
|  |    if (p->mapGenerationTime_ > 1440) | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(warning) | ||||||
|  |          << logPrefix_ << "Invalid time: " << p->mapGenerationTime_; | ||||||
|  |       messageValid = false; | ||||||
|  |    } | ||||||
|  |    if (numElevationSegments < 1 || numElevationSegments > 5) | ||||||
|  |    { | ||||||
|  |       BOOST_LOG_TRIVIAL(warning) | ||||||
|  |          << logPrefix_ | ||||||
|  |          << "Invalid number of elevation segments: " << numElevationSegments; | ||||||
|  |       messageValid = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (!messageValid) | ||||||
|  |    { | ||||||
|  |       numElevationSegments = 0; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    p->rangeBins_.resize(numElevationSegments); | ||||||
|  | 
 | ||||||
|  |    for (uint16_t e = 0; e < numElevationSegments && messageValid; e++) | ||||||
|  |    { | ||||||
|  |       p->rangeBins_[e].resize(NUM_RADIALS); | ||||||
|  | 
 | ||||||
|  |       is.seekg(2, std::ios_base::cur); // Segment number (redundant)
 | ||||||
|  | 
 | ||||||
|  |       for (uint16_t r = 0; r < NUM_RADIALS && messageValid; r++) | ||||||
|  |       { | ||||||
|  |          p->rangeBins_[e][r].resize(NUM_CODED_RANGE_BINS); | ||||||
|  | 
 | ||||||
|  |          is.read(reinterpret_cast<char*>(p->rangeBins_[e][r].data()), | ||||||
|  |                  NUM_RANGE_BINS / 8u); | ||||||
|  |          bytesRead += NUM_RANGE_BINS / 8u; | ||||||
|  | 
 | ||||||
|  |          SwapVector(p->rangeBins_[e][r]); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (!ValidateMessage(is, bytesRead)) | ||||||
|  |    { | ||||||
|  |       messageValid = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (!messageValid) | ||||||
|  |    { | ||||||
|  |       p->rangeBins_.resize(0); | ||||||
|  |       p->rangeBins_.shrink_to_fit(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return messageValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<ClutterFilterBypassMap> | ||||||
|  | ClutterFilterBypassMap::Create(Level2MessageHeader&& header, std::istream& is) | ||||||
|  | { | ||||||
|  |    std::shared_ptr<ClutterFilterBypassMap> message = | ||||||
|  |       std::make_shared<ClutterFilterBypassMap>(); | ||||||
|  |    message->set_header(std::move(header)); | ||||||
|  | 
 | ||||||
|  |    if (!message->Parse(is)) | ||||||
|  |    { | ||||||
|  |       message.reset(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return message; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace rda
 | ||||||
|  | } // namespace wsr88d
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| #include <scwx/wsr88d/rda/level2_message_factory.hpp> | #include <scwx/wsr88d/rda/level2_message_factory.hpp> | ||||||
| 
 | 
 | ||||||
| #include <scwx/util/vectorbuf.hpp> | #include <scwx/util/vectorbuf.hpp> | ||||||
|  | #include <scwx/wsr88d/rda/clutter_filter_bypass_map.hpp> | ||||||
| #include <scwx/wsr88d/rda/clutter_filter_map.hpp> | #include <scwx/wsr88d/rda/clutter_filter_map.hpp> | ||||||
| #include <scwx/wsr88d/rda/digital_radar_data.hpp> | #include <scwx/wsr88d/rda/digital_radar_data.hpp> | ||||||
| #include <scwx/wsr88d/rda/performance_maintenance_data.hpp> | #include <scwx/wsr88d/rda/performance_maintenance_data.hpp> | ||||||
|  | @ -31,6 +32,7 @@ static const std::unordered_map<uint8_t, CreateLevel2MessageFunction> create_ { | ||||||
|    {2, RdaStatusData::Create}, |    {2, RdaStatusData::Create}, | ||||||
|    {3, PerformanceMaintenanceData::Create}, |    {3, PerformanceMaintenanceData::Create}, | ||||||
|    {5, VolumeCoveragePatternData::Create}, |    {5, VolumeCoveragePatternData::Create}, | ||||||
|  |    {13, ClutterFilterBypassMap::Create}, | ||||||
|    {15, ClutterFilterMap::Create}, |    {15, ClutterFilterMap::Create}, | ||||||
|    {18, RdaAdaptationData::Create}, |    {18, RdaAdaptationData::Create}, | ||||||
|    {31, DigitalRadarData::Create}}; |    {31, DigitalRadarData::Create}}; | ||||||
|  |  | ||||||
|  | @ -48,7 +48,8 @@ set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp | ||||||
|                source/scwx/wsr88d/level3_file.cpp |                source/scwx/wsr88d/level3_file.cpp | ||||||
|                source/scwx/wsr88d/nexrad_file.cpp |                source/scwx/wsr88d/nexrad_file.cpp | ||||||
|                source/scwx/wsr88d/nexrad_file_factory.cpp) |                source/scwx/wsr88d/nexrad_file_factory.cpp) | ||||||
| set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp | set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp | ||||||
|  |                    include/scwx/wsr88d/rda/clutter_filter_map.hpp | ||||||
|                    include/scwx/wsr88d/rda/digital_radar_data.hpp |                    include/scwx/wsr88d/rda/digital_radar_data.hpp | ||||||
|                    include/scwx/wsr88d/rda/level2_message.hpp |                    include/scwx/wsr88d/rda/level2_message.hpp | ||||||
|                    include/scwx/wsr88d/rda/level2_message_factory.hpp |                    include/scwx/wsr88d/rda/level2_message_factory.hpp | ||||||
|  | @ -58,7 +59,8 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp | ||||||
|                    include/scwx/wsr88d/rda/rda_status_data.hpp |                    include/scwx/wsr88d/rda/rda_status_data.hpp | ||||||
|                    include/scwx/wsr88d/rda/types.hpp |                    include/scwx/wsr88d/rda/types.hpp | ||||||
|                    include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp) |                    include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp) | ||||||
| set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp | set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_bypass_map.cpp | ||||||
|  |                    source/scwx/wsr88d/rda/clutter_filter_map.cpp | ||||||
|                    source/scwx/wsr88d/rda/digital_radar_data.cpp |                    source/scwx/wsr88d/rda/digital_radar_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/level2_message.cpp |                    source/scwx/wsr88d/rda/level2_message.cpp | ||||||
|                    source/scwx/wsr88d/rda/level2_message_factory.cpp |                    source/scwx/wsr88d/rda/level2_message_factory.cpp | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat