mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:40:06 +00:00 
			
		
		
		
	Parse Volume Coverage Pattern Data (Message Type 5)
This commit is contained in:
		
							parent
							
								
									2fc12d44db
								
							
						
					
					
						commit
						517c77cb5f
					
				
					 7 changed files with 635 additions and 52 deletions
				
			
		|  | @ -91,32 +91,24 @@ bool ClutterFilterMap::Parse(std::istream& is) | |||
|    p->mapGenerationTime_ = htons(p->mapGenerationTime_); | ||||
|    numElevationSegments  = htons(numElevationSegments); | ||||
| 
 | ||||
|    if (is.eof()) | ||||
|    if (p->mapGenerationDate_ < 1) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Reached end of file (1)"; | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Invalid date: " << p->mapGenerationDate_; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    else | ||||
|    if (p->mapGenerationTime_ > 1440) | ||||
|    { | ||||
|       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; | ||||
|       } | ||||
|       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) | ||||
|  | @ -138,22 +130,13 @@ bool ClutterFilterMap::Parse(std::istream& is) | |||
| 
 | ||||
|          numRangeZones = htons(numRangeZones); | ||||
| 
 | ||||
|          if (is.eof()) | ||||
|          if (numRangeZones < 1 || numRangeZones > 20) | ||||
|          { | ||||
|             BOOST_LOG_TRIVIAL(warning) | ||||
|                << logPrefix_ << "Reached end of file (2)"; | ||||
|                << logPrefix_ | ||||
|                << "Invalid number of range zones: " << numRangeZones; | ||||
|             messageValid = false; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             if (numRangeZones < 1 || numRangeZones > 20) | ||||
|             { | ||||
|                BOOST_LOG_TRIVIAL(warning) | ||||
|                   << logPrefix_ | ||||
|                   << "Invalid number of range zones: " << numRangeZones; | ||||
|                messageValid = false; | ||||
|             } | ||||
|          } | ||||
| 
 | ||||
|          if (!messageValid) | ||||
|          { | ||||
|  | @ -173,26 +156,17 @@ bool ClutterFilterMap::Parse(std::istream& is) | |||
|             zone.opCode   = htons(zone.opCode); | ||||
|             zone.endRange = htons(zone.endRange); | ||||
| 
 | ||||
|             if (is.eof()) | ||||
|             if (zone.opCode > 2) | ||||
|             { | ||||
|                BOOST_LOG_TRIVIAL(warning) | ||||
|                   << logPrefix_ << "Reached end of file (3)"; | ||||
|                   << logPrefix_ << "Invalid op code: " << zone.opCode; | ||||
|                messageValid = false; | ||||
|             } | ||||
|             else | ||||
|             if (zone.endRange > 511) | ||||
|             { | ||||
|                if (zone.opCode > 2) | ||||
|                { | ||||
|                   BOOST_LOG_TRIVIAL(warning) | ||||
|                      << logPrefix_ << "Invalid op code: " << zone.opCode; | ||||
|                   messageValid = false; | ||||
|                } | ||||
|                if (zone.endRange > 511) | ||||
|                { | ||||
|                   BOOST_LOG_TRIVIAL(warning) | ||||
|                      << logPrefix_ << "Invalid end range: " << zone.endRange; | ||||
|                   messageValid = false; | ||||
|                } | ||||
|                BOOST_LOG_TRIVIAL(warning) | ||||
|                   << logPrefix_ << "Invalid end range: " << zone.endRange; | ||||
|                messageValid = false; | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ bool Message::ValidateMessage(std::istream& is, size_t bytesRead) const | |||
| 
 | ||||
|    if (is.eof()) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Reached end of file"; | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Reached end of data stream"; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    else if (is.fail()) | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #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/volume_coverage_pattern_data.hpp> | ||||
| 
 | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
|  | @ -24,6 +25,7 @@ typedef std::function<std::unique_ptr<Message>(MessageHeader&&, std::istream&)> | |||
| 
 | ||||
| static const std::unordered_map<uint8_t, CreateMessageFunction> create_ { | ||||
|    {3, PerformanceMaintenanceData::Create}, | ||||
|    {5, VolumeCoveragePatternData::Create}, | ||||
|    {15, ClutterFilterMap::Create}, | ||||
|    {18, RdaAdaptationData::Create}}; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										513
									
								
								wxdata/source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								wxdata/source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,513 @@ | |||
| #include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace wsr88d | ||||
| { | ||||
| namespace rda | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = | ||||
|    "[scwx::wsr88d::rda::volume_coverage_pattern_data] "; | ||||
| 
 | ||||
| struct Sector; | ||||
| 
 | ||||
| static void ReadSector(std::istream& is, Sector& s); | ||||
| static void SwapSector(Sector& s); | ||||
| 
 | ||||
| struct Sector | ||||
| { | ||||
|    uint16_t edgeAngle_; | ||||
|    uint16_t dopplerPrfNumber_; | ||||
|    uint16_t dopplerPrfPulseCountRadial_; | ||||
| 
 | ||||
|    Sector() : | ||||
|        edgeAngle_ {0}, dopplerPrfNumber_ {0}, dopplerPrfPulseCountRadial_ {0} | ||||
|    { | ||||
|    } | ||||
| }; | ||||
| 
 | ||||
| struct ElevationCut | ||||
| { | ||||
|    uint16_t              elevationAngle_; | ||||
|    uint8_t               channelConfiguration_; | ||||
|    uint8_t               waveformType_; | ||||
|    uint8_t               superResolutionControl_; | ||||
|    uint8_t               surveillancePrfNumber_; | ||||
|    uint16_t              surveillancePrfPulseCountRadial_; | ||||
|    int16_t               azimuthRate_; | ||||
|    uint16_t              reflectivityThreshold_; | ||||
|    uint16_t              velocityThreshold_; | ||||
|    uint16_t              spectrumWidthThreshold_; | ||||
|    uint16_t              differentialReflectivityThreshold_; | ||||
|    uint16_t              differentialPhaseThreshold_; | ||||
|    uint16_t              correlationCoefficientThreshold_; | ||||
|    std::array<Sector, 3> sector_; | ||||
|    uint16_t              supplementalData_; | ||||
|    uint16_t              ebcAngle_; | ||||
| 
 | ||||
|    ElevationCut() : | ||||
|        elevationAngle_ {0}, | ||||
|        channelConfiguration_ {0}, | ||||
|        waveformType_ {0}, | ||||
|        superResolutionControl_ {0}, | ||||
|        surveillancePrfNumber_ {0}, | ||||
|        surveillancePrfPulseCountRadial_ {0}, | ||||
|        azimuthRate_ {0}, | ||||
|        reflectivityThreshold_ {0}, | ||||
|        velocityThreshold_ {0}, | ||||
|        spectrumWidthThreshold_ {0}, | ||||
|        differentialReflectivityThreshold_ {0}, | ||||
|        differentialPhaseThreshold_ {0}, | ||||
|        correlationCoefficientThreshold_ {0}, | ||||
|        sector_(), | ||||
|        supplementalData_ {0}, | ||||
|        ebcAngle_ {0} | ||||
|    { | ||||
|    } | ||||
| }; | ||||
| 
 | ||||
| class VolumeCoveragePatternDataImpl | ||||
| { | ||||
| public: | ||||
|    explicit VolumeCoveragePatternDataImpl() : | ||||
|        patternType_ {0}, | ||||
|        patternNumber_ {0}, | ||||
|        version_ {0}, | ||||
|        clutterMapGroupNumber_ {0}, | ||||
|        dopplerVelocityResolution_ {0}, | ||||
|        pulseWidth_ {0}, | ||||
|        vcpSequencing_ {0}, | ||||
|        vcpSupplementalData_ {0}, | ||||
|        elevationCuts_() {}; | ||||
|    ~VolumeCoveragePatternDataImpl() = default; | ||||
| 
 | ||||
|    uint16_t                  patternType_; | ||||
|    uint16_t                  patternNumber_; | ||||
|    uint8_t                   version_; | ||||
|    uint8_t                   clutterMapGroupNumber_; | ||||
|    uint8_t                   dopplerVelocityResolution_; | ||||
|    uint8_t                   pulseWidth_; | ||||
|    uint16_t                  vcpSequencing_; | ||||
|    uint16_t                  vcpSupplementalData_; | ||||
|    std::vector<ElevationCut> elevationCuts_; | ||||
| }; | ||||
| 
 | ||||
| VolumeCoveragePatternData::VolumeCoveragePatternData() : | ||||
|     Message(), p(std::make_unique<VolumeCoveragePatternDataImpl>()) | ||||
| { | ||||
| } | ||||
| VolumeCoveragePatternData::~VolumeCoveragePatternData() = default; | ||||
| 
 | ||||
| VolumeCoveragePatternData::VolumeCoveragePatternData( | ||||
|    VolumeCoveragePatternData&&) noexcept                      = default; | ||||
| VolumeCoveragePatternData& VolumeCoveragePatternData::operator=( | ||||
|    VolumeCoveragePatternData&&) noexcept = default; | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::pattern_type() const | ||||
| { | ||||
|    return p->patternType_; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::pattern_number() const | ||||
| { | ||||
|    return p->patternNumber_; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::number_of_elevation_cuts() const | ||||
| { | ||||
|    return static_cast<uint16_t>(p->elevationCuts_.size()); | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::version() const | ||||
| { | ||||
|    return p->version_; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::clutter_map_group_number() const | ||||
| { | ||||
|    return p->clutterMapGroupNumber_; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::doppler_velocity_resolution() const | ||||
| { | ||||
|    float resolution = 0.0f; | ||||
| 
 | ||||
|    switch (p->dopplerVelocityResolution_) | ||||
|    { | ||||
|    case 2: resolution = 0.5f; break; | ||||
|    case 4: resolution = 1.0f; break; | ||||
|    } | ||||
| 
 | ||||
|    return resolution; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::pulse_width() const | ||||
| { | ||||
|    return p->pulseWidth_; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::vcp_sequencing() const | ||||
| { | ||||
|    return p->vcpSequencing_; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::number_of_elevations() const | ||||
| { | ||||
|    return p->vcpSequencing_ & 0x001f; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::maximum_sails_cuts() const | ||||
| { | ||||
|    return (p->vcpSequencing_ & 0x0060) >> 5; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::sequence_active() const | ||||
| { | ||||
|    return p->vcpSequencing_ & 0x2000; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::truncated_vcp() const | ||||
| { | ||||
|    return p->vcpSequencing_ & 0x4000; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::vcp_supplemental_data() const | ||||
| { | ||||
|    return p->vcpSupplementalData_; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::sails_vcp() const | ||||
| { | ||||
|    return p->vcpSupplementalData_ & 0x0001; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::number_of_sails_cuts() const | ||||
| { | ||||
|    return (p->vcpSupplementalData_ & 0x000E) >> 1; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::mrle_vcp() const | ||||
| { | ||||
|    return p->vcpSupplementalData_ & 0x0010; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::number_of_mrle_cuts() const | ||||
| { | ||||
|    return (p->vcpSupplementalData_ & 0x00E0) >> 5; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::mpda_vcp() const | ||||
| { | ||||
|    return p->vcpSupplementalData_ & 0x0800; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::base_tilt_vcp() const | ||||
| { | ||||
|    return p->vcpSupplementalData_ & 0x1000; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::number_of_base_tilts() const | ||||
| { | ||||
|    return (p->vcpSupplementalData_ & 0xE000) >> 13; | ||||
| } | ||||
| 
 | ||||
| double VolumeCoveragePatternData::elevation_angle(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].elevationAngle_ * ANGLE_DATA_SCALE; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::channel_configuration(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].channelConfiguration_; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::waveform_type(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].waveformType_; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::super_resolution_control(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::half_degree_azimuth(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0001; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::quarter_km_reflectivity(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0002; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::doppler_to_300km(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0004; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::dual_polarization_to_300km(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].superResolutionControl_ & 0x0008; | ||||
| } | ||||
| 
 | ||||
| uint8_t VolumeCoveragePatternData::surveillance_prf_number(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].surveillancePrfNumber_; | ||||
| } | ||||
| 
 | ||||
| uint16_t | ||||
| VolumeCoveragePatternData::surveillance_prf_pulse_count_radial(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].surveillancePrfPulseCountRadial_; | ||||
| } | ||||
| 
 | ||||
| double VolumeCoveragePatternData::azimuth_rate(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].azimuthRate_ * AZ_EL_RATE_DATA_SCALE; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::reflectivity_threshold(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].reflectivityThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::velocity_threshold(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].velocityThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::spectrum_width_threshold(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].spectrumWidthThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::differential_reflectivity_threshold( | ||||
|    uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].differentialReflectivityThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::differential_phase_threshold(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].differentialPhaseThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| float VolumeCoveragePatternData::correlation_coefficient_threshold( | ||||
|    uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].correlationCoefficientThreshold_ * 0.125f; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::supplemental_data(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].supplementalData_; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::sails_cut(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].supplementalData_ & 0x0001; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::sails_sequence_number(uint16_t e) const | ||||
| { | ||||
|    return (p->elevationCuts_[e].supplementalData_ & 0x000E) >> 1; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::mrle_cut(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].supplementalData_ & 0x0010; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::mrle_sequence_number(uint16_t e) const | ||||
| { | ||||
|    return (p->elevationCuts_[e].supplementalData_ & 0x00E0) >> 5; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::mpda_cut(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].supplementalData_ & 0x0200; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::base_tilt_cut(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].supplementalData_ & 0x0400; | ||||
| } | ||||
| 
 | ||||
| double VolumeCoveragePatternData::ebc_angle(uint16_t e) const | ||||
| { | ||||
|    return p->elevationCuts_[e].ebcAngle_ * ANGLE_DATA_SCALE; | ||||
| } | ||||
| 
 | ||||
| double VolumeCoveragePatternData::edge_angle(uint16_t e, uint16_t s) const | ||||
| { | ||||
|    return p->elevationCuts_[e].sector_[s].edgeAngle_ * ANGLE_DATA_SCALE; | ||||
| } | ||||
| 
 | ||||
| uint16_t VolumeCoveragePatternData::doppler_prf_number(uint16_t e, | ||||
|                                                        uint16_t s) const | ||||
| { | ||||
|    return p->elevationCuts_[e].sector_[s].dopplerPrfNumber_; | ||||
| } | ||||
| 
 | ||||
| uint16_t | ||||
| VolumeCoveragePatternData::doppler_prf_pulse_count_radial(uint16_t e, | ||||
|                                                           uint16_t s) const | ||||
| { | ||||
|    return p->elevationCuts_[e].sector_[s].dopplerPrfPulseCountRadial_; | ||||
| } | ||||
| 
 | ||||
| bool VolumeCoveragePatternData::Parse(std::istream& is) | ||||
| { | ||||
|    BOOST_LOG_TRIVIAL(debug) | ||||
|       << logPrefix_ << "Parsing Volume Coverage Pattern Data (Message Type 5)"; | ||||
| 
 | ||||
|    bool   messageValid = true; | ||||
|    size_t bytesRead    = 0; | ||||
| 
 | ||||
|    uint16_t messageSize           = 0; | ||||
|    uint16_t numberOfElevationCuts = 0; | ||||
| 
 | ||||
|    is.read(reinterpret_cast<char*>(&messageSize), 2);                   // 1
 | ||||
|    is.read(reinterpret_cast<char*>(&p->patternType_), 2);               // 2
 | ||||
|    is.read(reinterpret_cast<char*>(&p->patternNumber_), 2);             // 3
 | ||||
|    is.read(reinterpret_cast<char*>(&numberOfElevationCuts), 2);         // 4
 | ||||
|    is.read(reinterpret_cast<char*>(&p->version_), 1);                   // 5
 | ||||
|    is.read(reinterpret_cast<char*>(&p->clutterMapGroupNumber_), 1);     // 5
 | ||||
|    is.read(reinterpret_cast<char*>(&p->dopplerVelocityResolution_), 1); // 6
 | ||||
|    is.read(reinterpret_cast<char*>(&p->pulseWidth_), 1);                // 6
 | ||||
|    is.seekg(4, std::ios_base::cur);                                     // 7-8
 | ||||
|    is.read(reinterpret_cast<char*>(&p->vcpSequencing_), 2);             // 9
 | ||||
|    is.read(reinterpret_cast<char*>(&p->vcpSupplementalData_), 2);       // 10
 | ||||
|    is.seekg(2, std::ios_base::cur);                                     // 11
 | ||||
|    bytesRead += 22; | ||||
| 
 | ||||
|    messageSize             = htons(messageSize); | ||||
|    p->patternType_         = htons(p->patternType_); | ||||
|    p->patternNumber_       = htons(p->patternNumber_); | ||||
|    numberOfElevationCuts   = htons(numberOfElevationCuts); | ||||
|    p->vcpSequencing_       = htons(p->vcpSequencing_); | ||||
|    p->vcpSupplementalData_ = htons(p->vcpSupplementalData_); | ||||
| 
 | ||||
|    if (messageSize < 34 || messageSize > 747) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Invalid message size: " << messageSize; | ||||
|       messageValid = false; | ||||
|    } | ||||
|    if (numberOfElevationCuts < 1 || numberOfElevationCuts > 32) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ | ||||
|          << "Invalid number of elevation cuts: " << numberOfElevationCuts; | ||||
|       messageValid = false; | ||||
|    } | ||||
| 
 | ||||
|    if (!messageValid) | ||||
|    { | ||||
|       numberOfElevationCuts = 0; | ||||
|    } | ||||
| 
 | ||||
|    p->elevationCuts_.resize(numberOfElevationCuts); | ||||
| 
 | ||||
|    for (uint16_t e = 0; e < numberOfElevationCuts; ++e) | ||||
|    { | ||||
|       ElevationCut& c = p->elevationCuts_[e]; | ||||
| 
 | ||||
|       is.read(reinterpret_cast<char*>(&c.elevationAngle_), 2);         // E1
 | ||||
|       is.read(reinterpret_cast<char*>(&c.channelConfiguration_), 1);   // E2
 | ||||
|       is.read(reinterpret_cast<char*>(&c.waveformType_), 1);           // E2
 | ||||
|       is.read(reinterpret_cast<char*>(&c.superResolutionControl_), 1); // E3
 | ||||
|       is.read(reinterpret_cast<char*>(&c.surveillancePrfNumber_), 1);  // E3
 | ||||
|       is.read(reinterpret_cast<char*>(&c.surveillancePrfPulseCountRadial_), | ||||
|               2);                                                      // E4
 | ||||
|       is.read(reinterpret_cast<char*>(&c.azimuthRate_), 2);            // E5
 | ||||
|       is.read(reinterpret_cast<char*>(&c.reflectivityThreshold_), 2);  // E6
 | ||||
|       is.read(reinterpret_cast<char*>(&c.velocityThreshold_), 2);      // E7
 | ||||
|       is.read(reinterpret_cast<char*>(&c.spectrumWidthThreshold_), 2); // E8
 | ||||
|       is.read(reinterpret_cast<char*>(&c.differentialReflectivityThreshold_), | ||||
|               2); // E9
 | ||||
|       is.read(reinterpret_cast<char*>(&c.differentialPhaseThreshold_), | ||||
|               2); // E10
 | ||||
|       is.read(reinterpret_cast<char*>(&c.correlationCoefficientThreshold_), | ||||
|               2);                                                // E11
 | ||||
|       ReadSector(is, c.sector_[0]);                              // E12-E14
 | ||||
|       is.read(reinterpret_cast<char*>(&c.supplementalData_), 2); // E15
 | ||||
|       ReadSector(is, c.sector_[1]);                              // E16-E18
 | ||||
|       is.read(reinterpret_cast<char*>(&c.ebcAngle_), 2);         // E19
 | ||||
|       ReadSector(is, c.sector_[2]);                              // E20-E22
 | ||||
|       is.seekg(2, std::ios_base::cur);                           // E23
 | ||||
|       bytesRead += 46; | ||||
| 
 | ||||
|       c.elevationAngle_ = htons(c.elevationAngle_); | ||||
|       c.surveillancePrfPulseCountRadial_ = | ||||
|          htons(c.surveillancePrfPulseCountRadial_); | ||||
|       c.azimuthRate_            = htons(c.azimuthRate_); | ||||
|       c.reflectivityThreshold_  = htons(c.reflectivityThreshold_); | ||||
|       c.velocityThreshold_      = htons(c.velocityThreshold_); | ||||
|       c.spectrumWidthThreshold_ = htons(c.spectrumWidthThreshold_); | ||||
|       c.differentialReflectivityThreshold_ = | ||||
|          htons(c.differentialReflectivityThreshold_); | ||||
|       c.differentialPhaseThreshold_ = htons(c.differentialPhaseThreshold_); | ||||
|       c.correlationCoefficientThreshold_ = | ||||
|          htons(c.correlationCoefficientThreshold_); | ||||
|       c.supplementalData_ = htons(c.supplementalData_); | ||||
|       c.ebcAngle_         = htons(c.ebcAngle_); | ||||
| 
 | ||||
|       for (size_t s = 0; s < c.sector_.size(); s++) | ||||
|       { | ||||
|          SwapSector(c.sector_[s]); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    if (messageValid && bytesRead != messageSize * 2) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Bytes read (" << bytesRead | ||||
|          << ") not equal to message size (" << messageSize * 2 << ")"; | ||||
|    } | ||||
| 
 | ||||
|    if (!ValidateMessage(is, bytesRead)) | ||||
|    { | ||||
|       messageValid = false; | ||||
|    } | ||||
| 
 | ||||
|    if (!messageValid) | ||||
|    { | ||||
|       p->elevationCuts_.resize(0); | ||||
|       p->elevationCuts_.shrink_to_fit(); | ||||
|    } | ||||
| 
 | ||||
|    return messageValid; | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<VolumeCoveragePatternData> | ||||
| VolumeCoveragePatternData::Create(MessageHeader&& header, std::istream& is) | ||||
| { | ||||
|    std::unique_ptr<VolumeCoveragePatternData> message = | ||||
|       std::make_unique<VolumeCoveragePatternData>(); | ||||
|    message->set_header(std::move(header)); | ||||
|    message->Parse(is); | ||||
|    return message; | ||||
| } | ||||
| 
 | ||||
| static void ReadSector(std::istream& is, Sector& s) | ||||
| { | ||||
|    is.read(reinterpret_cast<char*>(&s.edgeAngle_), 2);                  // S1
 | ||||
|    is.read(reinterpret_cast<char*>(&s.dopplerPrfNumber_), 2);           // S2
 | ||||
|    is.read(reinterpret_cast<char*>(&s.dopplerPrfPulseCountRadial_), 2); // S3
 | ||||
| } | ||||
| 
 | ||||
| static void SwapSector(Sector& s) | ||||
| { | ||||
|    s.edgeAngle_                  = htons(s.edgeAngle_); | ||||
|    s.dopplerPrfNumber_           = htons(s.dopplerPrfNumber_); | ||||
|    s.dopplerPrfPulseCountRadial_ = htons(s.dopplerPrfPulseCountRadial_); | ||||
| } | ||||
| 
 | ||||
| } // namespace rda
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat