mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 17:30:05 +00:00 
			
		
		
		
	Finish parsing Storm Position / Forecast page
This commit is contained in:
		
							parent
							
								
									0415223571
								
							
						
					
					
						commit
						925f91995a
					
				
					 4 changed files with 127 additions and 9 deletions
				
			
		|  | @ -30,6 +30,8 @@ std::vector<std::string> ParseTokens(const std::string&       s, | |||
| 
 | ||||
| std::string ToString(const std::vector<std::string>& v); | ||||
| 
 | ||||
| std::optional<float> TryParseFloat(const std::string& str); | ||||
| 
 | ||||
| template<typename T> | ||||
| std::optional<T> TryParseUnsignedLong(const std::string& str); | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,21 +22,21 @@ public: | |||
|    { | ||||
|       struct Position | ||||
|       { | ||||
|          std::optional<units::angle::degrees<float>>         azimuth_ {}; | ||||
|          std::optional<units::length::nautical_miles<float>> range_ {}; | ||||
|          std::optional<units::angle::degrees<std::uint16_t>> azimuth_ {}; | ||||
|          std::optional<units::length::nautical_miles<std::uint16_t>> range_ {}; | ||||
|       }; | ||||
| 
 | ||||
|       Position                                     currentPosition_ {}; | ||||
|       std::optional<units::angle::degrees<float>>  direction_; | ||||
|       std::optional<units::velocity::knots<float>> speed_; | ||||
|       Position                                             currentPosition_ {}; | ||||
|       std::optional<units::angle::degrees<std::uint16_t>>  direction_; | ||||
|       std::optional<units::velocity::knots<std::uint16_t>> speed_; | ||||
| 
 | ||||
|       std::array<Position, 4> forecastPosition_ {}; | ||||
| 
 | ||||
|       std::optional<units::length::nautical_miles<float>> forecastError_ {}; | ||||
|       std::optional<units::length::nautical_miles<float>> meanError_ {}; | ||||
| 
 | ||||
|       std::optional<std::int16_t>               maxDbz_ {}; | ||||
|       std::optional<units::length::feet<float>> maxDbzHeight_ {}; | ||||
|       std::optional<std::int16_t>                       maxDbz_ {}; | ||||
|       std::optional<units::length::feet<std::uint32_t>> maxDbzHeight_ {}; | ||||
|    }; | ||||
| 
 | ||||
|    explicit StormTrackingInformationMessage(); | ||||
|  |  | |||
|  | @ -88,6 +88,21 @@ std::string ToString(const std::vector<std::string>& v) | |||
|    return value; | ||||
| } | ||||
| 
 | ||||
| std::optional<float> TryParseFloat(const std::string& str) | ||||
| { | ||||
|    std::optional<float> value = std::nullopt; | ||||
| 
 | ||||
|    try | ||||
|    { | ||||
|       value = static_cast<float>(std::stof(str)); | ||||
|    } | ||||
|    catch (const std::exception&) | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    return value; | ||||
| } | ||||
| 
 | ||||
| template<typename T> | ||||
| std::optional<T> TryParseUnsignedLong(const std::string& str) | ||||
| { | ||||
|  |  | |||
|  | @ -143,9 +143,110 @@ void StormTrackingInformationMessage::Impl::ParseStormPositionForecastPage( | |||
|       // clang-format on
 | ||||
|       else if (i >= 7 && line.size() >= 80) | ||||
|       { | ||||
|          // TODO: STI Record
 | ||||
|          std::string stormId = line.substr(2, 2); | ||||
|          (void) (stormId); | ||||
| 
 | ||||
|          if (std::isupper(stormId[0]) && std::isdigit(stormId[1])) | ||||
|          { | ||||
|             auto& record = stiRecords_[stormId]; | ||||
| 
 | ||||
|             if (record.currentPosition_.azimuth_ == std::nullopt) | ||||
|             { | ||||
|                // Current Position: Azimuth (Degrees)
 | ||||
|                auto azimuth = | ||||
|                   util::TryParseUnsignedLong<std::uint16_t>(line.substr(9, 3)); | ||||
|                if (azimuth.has_value()) | ||||
|                { | ||||
|                   record.currentPosition_.azimuth_ = | ||||
|                      units::angle::degrees<std::uint16_t> {azimuth.value()}; | ||||
|                } | ||||
|             } | ||||
|             if (record.currentPosition_.range_ == std::nullopt) | ||||
|             { | ||||
|                // Current Position: Range (Nautical Miles)
 | ||||
|                auto range = | ||||
|                   util::TryParseUnsignedLong<std::uint16_t>(line.substr(13, 3)); | ||||
|                if (range.has_value()) | ||||
|                { | ||||
|                   record.currentPosition_.range_ = | ||||
|                      units::length::nautical_miles<std::uint16_t> { | ||||
|                         range.value()}; | ||||
|                } | ||||
|             } | ||||
|             if (record.direction_ == std::nullopt) | ||||
|             { | ||||
|                // Movement: Direction (Degrees)
 | ||||
|                auto direction = | ||||
|                   util::TryParseUnsignedLong<std::uint16_t>(line.substr(19, 3)); | ||||
|                if (direction.has_value()) | ||||
|                { | ||||
|                   record.direction_ = | ||||
|                      units::angle::degrees<std::uint16_t> {direction.value()}; | ||||
|                } | ||||
|             } | ||||
|             if (record.speed_ == std::nullopt) | ||||
|             { | ||||
|                // Movement: Speed (Knots)
 | ||||
|                auto speed = | ||||
|                   util::TryParseUnsignedLong<std::uint16_t>(line.substr(23, 3)); | ||||
|                if (speed.has_value()) | ||||
|                { | ||||
|                   record.speed_ = | ||||
|                      units::velocity::knots<std::uint16_t> {speed.value()}; | ||||
|                } | ||||
|             } | ||||
|             for (std::size_t j = 0; j < record.forecastPosition_.size(); ++j) | ||||
|             { | ||||
|                const std::size_t positionOffset = j * 10; | ||||
| 
 | ||||
|                if (record.forecastPosition_[j].azimuth_ == std::nullopt) | ||||
|                { | ||||
|                   // Forecast Position: Azimuth (Degrees)
 | ||||
|                   std::size_t offset = 31 + positionOffset; | ||||
| 
 | ||||
|                   auto azimuth = util::TryParseUnsignedLong<std::uint16_t>( | ||||
|                      line.substr(offset, 3)); | ||||
|                   if (azimuth.has_value()) | ||||
|                   { | ||||
|                      record.forecastPosition_[j].azimuth_ = | ||||
|                         units::angle::degrees<std::uint16_t> {azimuth.value()}; | ||||
|                   } | ||||
|                } | ||||
|                if (record.forecastPosition_[j].range_ == std::nullopt) | ||||
|                { | ||||
|                   // Forecast Position: Range (Nautical Miles)
 | ||||
|                   std::size_t offset = 35 + positionOffset; | ||||
| 
 | ||||
|                   auto range = util::TryParseUnsignedLong<std::uint16_t>( | ||||
|                      line.substr(offset, 3)); | ||||
|                   if (range.has_value()) | ||||
|                   { | ||||
|                      record.forecastPosition_[j].range_ = | ||||
|                         units::length::nautical_miles<std::uint16_t> { | ||||
|                            range.value()}; | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|             if (record.forecastError_ == std::nullopt) | ||||
|             { | ||||
|                // Forecast Error (Nautical Miles)
 | ||||
|                auto forecastError = util::TryParseFloat(line.substr(71, 4)); | ||||
|                if (forecastError.has_value()) | ||||
|                { | ||||
|                   record.forecastError_ = units::length::nautical_miles<float> { | ||||
|                      forecastError.value()}; | ||||
|                } | ||||
|             } | ||||
|             if (record.meanError_ == std::nullopt) | ||||
|             { | ||||
|                // Mean Error (Nautical Miles)
 | ||||
|                auto meanError = util::TryParseFloat(line.substr(76, 4)); | ||||
|                if (meanError.has_value()) | ||||
|                { | ||||
|                   record.meanError_ = | ||||
|                      units::length::nautical_miles<float> {meanError.value()}; | ||||
|                } | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat