mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 06:50:06 +00:00 
			
		
		
		
	Store radar data in Ar2vFile object
This commit is contained in:
		
							parent
							
								
									79ab14ab95
								
							
						
					
					
						commit
						a2c6ee70a4
					
				
					 18 changed files with 183 additions and 39 deletions
				
			
		|  | @ -1,2 +1,8 @@ | |||
| cmake_minimum_required(VERSION 3.11) | ||||
| 
 | ||||
| set_property(DIRECTORY | ||||
|              APPEND | ||||
|              PROPERTY CMAKE_CONFIGURE_DEPENDS | ||||
|              wxdata.cmake) | ||||
| 
 | ||||
| include(wxdata.cmake) | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<ClutterFilterMap> Create(MessageHeader&& header, | ||||
|    static std::shared_ptr<ClutterFilterMap> Create(MessageHeader&& header, | ||||
|                                                    std::istream&   is); | ||||
| 
 | ||||
|    static const size_t NUM_AZIMUTH_SEGMENTS = 360u; | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<DigitalRadarData> Create(MessageHeader&& header, | ||||
|    static std::shared_ptr<DigitalRadarData> Create(MessageHeader&& header, | ||||
|                                                    std::istream&   is); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ namespace rda | |||
| 
 | ||||
| struct MessageInfo | ||||
| { | ||||
|    std::unique_ptr<Message> message; | ||||
|    std::shared_ptr<Message> message; | ||||
|    bool                     headerValid; | ||||
|    bool                     messageValid; | ||||
| 
 | ||||
|  |  | |||
|  | @ -278,7 +278,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<PerformanceMaintenanceData> | ||||
|    static std::shared_ptr<PerformanceMaintenanceData> | ||||
|    Create(MessageHeader&& header, std::istream& is); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -203,7 +203,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<RdaAdaptationData> Create(MessageHeader&& header, | ||||
|    static std::shared_ptr<RdaAdaptationData> Create(MessageHeader&& header, | ||||
|                                                     std::istream&   is); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<RdaStatusData> Create(MessageHeader&& header, | ||||
|    static std::shared_ptr<RdaStatusData> Create(MessageHeader&& header, | ||||
|                                                 std::istream&   is); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
							
								
								
									
										22
									
								
								wxdata/include/scwx/wsr88d/rda/types.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								wxdata/include/scwx/wsr88d/rda/types.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #pragma once | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace wsr88d | ||||
| { | ||||
| namespace rda | ||||
| { | ||||
| 
 | ||||
| enum class MessageId : uint8_t | ||||
| { | ||||
|    RdaStatusData              = 2, | ||||
|    PerformanceMaintenanceData = 3, | ||||
|    VolumeCoveragePatternData  = 5, | ||||
|    ClutterFilterMap           = 15, | ||||
|    RdaAdaptationData          = 18, | ||||
|    DigitalRadarData           = 31 | ||||
| }; | ||||
| 
 | ||||
| } // namespace rda
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
|  | @ -77,7 +77,7 @@ public: | |||
| 
 | ||||
|    bool Parse(std::istream& is); | ||||
| 
 | ||||
|    static std::unique_ptr<VolumeCoveragePatternData> | ||||
|    static std::shared_ptr<VolumeCoveragePatternData> | ||||
|    Create(MessageHeader&& header, std::istream& is); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| #include <scwx/wsr88d/ar2v_file.hpp> | ||||
| #include <scwx/wsr88d/rda/digital_radar_data.hpp> | ||||
| #include <scwx/wsr88d/rda/message_factory.hpp> | ||||
| #include <scwx/wsr88d/rda/types.hpp> | ||||
| #include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp> | ||||
| #include <scwx/util/rangebuf.hpp> | ||||
| 
 | ||||
| #include <fstream> | ||||
|  | @ -27,11 +30,16 @@ public: | |||
|        milliseconds_ {0}, | ||||
|        icao_(), | ||||
|        numRecords_ {0}, | ||||
|        rawRecords_() {}; | ||||
|        rawRecords_(), | ||||
|        vcpData_ {nullptr}, | ||||
|        radarData_ {} {}; | ||||
|    ~Ar2vFileImpl() = default; | ||||
| 
 | ||||
|    void HandleMessage(std::shared_ptr<rda::Message>& message); | ||||
|    void LoadLDMRecords(std::ifstream& f); | ||||
|    void ParseLDMRecords(); | ||||
|    void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData>& message); | ||||
|    void ProcessVcpData(); | ||||
| 
 | ||||
|    std::string tapeFilename_; | ||||
|    std::string extensionNumber_; | ||||
|  | @ -41,6 +49,12 @@ public: | |||
| 
 | ||||
|    size_t numRecords_; | ||||
| 
 | ||||
|    std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_; | ||||
|    std::unordered_map< | ||||
|       uint16_t, | ||||
|       std::unordered_map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>> | ||||
|       radarData_; | ||||
| 
 | ||||
|    std::list<std::stringstream> rawRecords_; | ||||
| }; | ||||
| 
 | ||||
|  | @ -182,6 +196,11 @@ void Ar2vFileImpl::ParseLDMRecords() | |||
|             break; | ||||
|          } | ||||
| 
 | ||||
|          if (msgInfo.messageValid) | ||||
|          { | ||||
|             HandleMessage(msgInfo.message); | ||||
|          } | ||||
| 
 | ||||
|          off_t    offset   = 0; | ||||
|          uint16_t nextSize = 0u; | ||||
|          do | ||||
|  | @ -206,5 +225,51 @@ void Ar2vFileImpl::ParseLDMRecords() | |||
|    } | ||||
| } | ||||
| 
 | ||||
| void Ar2vFileImpl::HandleMessage(std::shared_ptr<rda::Message>& message) | ||||
| { | ||||
|    switch (message->header().message_type()) | ||||
|    { | ||||
|    case static_cast<uint8_t>(rda::MessageId::VolumeCoveragePatternData): | ||||
|       vcpData_ = | ||||
|          std::static_pointer_cast<rda::VolumeCoveragePatternData>(message); | ||||
|       ProcessVcpData(); | ||||
|       break; | ||||
| 
 | ||||
|    case static_cast<uint8_t>(rda::MessageId::DigitalRadarData): | ||||
|       ProcessRadarData( | ||||
|          std::static_pointer_cast<rda::DigitalRadarData>(message)); | ||||
|       break; | ||||
| 
 | ||||
|    default: break; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void Ar2vFileImpl::ProcessRadarData( | ||||
|    std::shared_ptr<rda::DigitalRadarData>& message) | ||||
| { | ||||
|    uint16_t azimuthIndex   = message->azimuth_number() - 1; | ||||
|    uint16_t elevationIndex = message->elevation_number() - 1; | ||||
| 
 | ||||
|    radarData_[elevationIndex][azimuthIndex] = message; | ||||
| } | ||||
| 
 | ||||
| void Ar2vFileImpl::ProcessVcpData() | ||||
| { | ||||
|    uint16_t numberOfElevationCuts = vcpData_->number_of_elevation_cuts(); | ||||
|    radarData_.reserve(numberOfElevationCuts); | ||||
| 
 | ||||
|    for (uint16_t e = 0; e < numberOfElevationCuts; ++e) | ||||
|    { | ||||
|       if (vcpData_->half_degree_azimuth(e)) | ||||
|       { | ||||
|          radarData_[e].reserve(720); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          radarData_[e].reserve(360); | ||||
|       } | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -186,13 +186,18 @@ bool ClutterFilterMap::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<ClutterFilterMap> | ||||
| std::shared_ptr<ClutterFilterMap> | ||||
| ClutterFilterMap::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<ClutterFilterMap> message = | ||||
|       std::make_unique<ClutterFilterMap>(); | ||||
|    std::shared_ptr<ClutterFilterMap> message = | ||||
|       std::make_shared<ClutterFilterMap>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -501,19 +501,34 @@ bool DigitalRadarData::Parse(std::istream& is) | |||
|    p->elevationAngle_     = SwapFloat(p->elevationAngle_); | ||||
|    p->dataBlockCount_     = ntohs(p->dataBlockCount_); | ||||
| 
 | ||||
|    if (p->azimuthNumber_ < 1 || p->azimuthNumber_ > 720) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Invalid azimuth number: " << p->azimuthNumber_; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    if (p->elevationNumber_ < 1 || p->elevationNumber_ > 32) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Invalid elevation number: " << p->elevationNumber_; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    if (p->dataBlockCount_ < 4 || p->dataBlockCount_ > 10) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ | ||||
|          << "Invalid number of data blocks: " << p->dataBlockCount_; | ||||
|       p->dataBlockCount_ = 0; | ||||
|       messageValid       = false; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    if (p->compressionIndicator_ != 0) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Compression not supported"; | ||||
|       messageValid = false; | ||||
|    } | ||||
| 
 | ||||
|    if (!messageValid) | ||||
|    { | ||||
|       p->dataBlockCount_ = 0; | ||||
|       messageValid       = false; | ||||
|    } | ||||
| 
 | ||||
|    is.read(reinterpret_cast<char*>(&p->dataBlockPointer_), | ||||
|  | @ -599,13 +614,18 @@ bool DigitalRadarData::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<DigitalRadarData> | ||||
| std::shared_ptr<DigitalRadarData> | ||||
| DigitalRadarData::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<DigitalRadarData> message = | ||||
|       std::make_unique<DigitalRadarData>(); | ||||
|    std::shared_ptr<DigitalRadarData> message = | ||||
|       std::make_shared<DigitalRadarData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ namespace rda | |||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::wsr88d::rda::message_factory] "; | ||||
| 
 | ||||
| typedef std::function<std::unique_ptr<Message>(MessageHeader&&, std::istream&)> | ||||
| typedef std::function<std::shared_ptr<Message>(MessageHeader&&, std::istream&)> | ||||
|    CreateMessageFunction; | ||||
| 
 | ||||
| static const std::unordered_map<uint8_t, CreateMessageFunction> create_ { | ||||
|  | @ -133,6 +133,11 @@ MessageInfo MessageFactory::Create(std::istream& is) | |||
|                std::ios_base::cur); | ||||
|    } | ||||
| 
 | ||||
|    if (info.message == nullptr) | ||||
|    { | ||||
|       info.messageValid = false; | ||||
|    } | ||||
| 
 | ||||
|    return info; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2468,13 +2468,18 @@ bool PerformanceMaintenanceData::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<PerformanceMaintenanceData> | ||||
| std::shared_ptr<PerformanceMaintenanceData> | ||||
| PerformanceMaintenanceData::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<PerformanceMaintenanceData> message = | ||||
|       std::make_unique<PerformanceMaintenanceData>(); | ||||
|    std::shared_ptr<PerformanceMaintenanceData> message = | ||||
|       std::make_shared<PerformanceMaintenanceData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1746,13 +1746,18 @@ bool RdaAdaptationData::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<RdaAdaptationData> | ||||
| std::shared_ptr<RdaAdaptationData> | ||||
| RdaAdaptationData::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<RdaAdaptationData> message = | ||||
|       std::make_unique<RdaAdaptationData>(); | ||||
|    std::shared_ptr<RdaAdaptationData> message = | ||||
|       std::make_shared<RdaAdaptationData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -322,12 +322,17 @@ bool RdaStatusData::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<RdaStatusData> RdaStatusData::Create(MessageHeader&& header, | ||||
| std::shared_ptr<RdaStatusData> RdaStatusData::Create(MessageHeader&& header, | ||||
|                                                      std::istream&   is) | ||||
| { | ||||
|    std::unique_ptr<RdaStatusData> message = std::make_unique<RdaStatusData>(); | ||||
|    std::shared_ptr<RdaStatusData> message = std::make_shared<RdaStatusData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -236,22 +236,22 @@ uint8_t VolumeCoveragePatternData::super_resolution_control(uint16_t e) const | |||
| 
 | ||||
| bool VolumeCoveragePatternData::half_degree_azimuth(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0001; | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x01; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::quarter_km_reflectivity(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0002; | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x02; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::doppler_to_300km(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0004; | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x04; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::dual_polarization_to_300km(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0008; | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x08; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::surveillance_prf_number(uint16_t e) const | ||||
|  | @ -484,13 +484,18 @@ bool VolumeCoveragePatternData::Parse(std::istream& is) | |||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<VolumeCoveragePatternData> | ||||
| std::shared_ptr<VolumeCoveragePatternData> | ||||
| VolumeCoveragePatternData::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<VolumeCoveragePatternData> message = | ||||
|       std::make_unique<VolumeCoveragePatternData>(); | ||||
|    std::shared_ptr<VolumeCoveragePatternData> message = | ||||
|       std::make_shared<VolumeCoveragePatternData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
| 
 | ||||
|    if (!message->Parse(is)) | ||||
|    { | ||||
|       message.reset(); | ||||
|    } | ||||
| 
 | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp | |||
|                    include/scwx/wsr88d/rda/performance_maintenance_data.hpp | ||||
|                    include/scwx/wsr88d/rda/rda_adaptation_data.hpp | ||||
|                    include/scwx/wsr88d/rda/rda_status_data.hpp | ||||
|                    include/scwx/wsr88d/rda/types.hpp | ||||
|                    include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp) | ||||
| set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp | ||||
|                    source/scwx/wsr88d/rda/digital_radar_data.cpp | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat