mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 09:50:06 +00:00 
			
		
		
		
	
							parent
							
								
									bd359fa7f2
								
							
						
					
					
						commit
						0952c0f90c
					
				
					 6 changed files with 100 additions and 10 deletions
				
			
		|  | @ -362,7 +362,8 @@ bool RadarProductLayer::RunMousePicking( | ||||||
| 
 | 
 | ||||||
|          if (code.has_value() && //
 |          if (code.has_value() && //
 | ||||||
|              code.value() != wsr88d::DataLevelCode::Blank && |              code.value() != wsr88d::DataLevelCode::Blank && | ||||||
|              code.value() != wsr88d::DataLevelCode::NoData) |              code.value() != wsr88d::DataLevelCode::NoData && | ||||||
|  |              code.value() != wsr88d::DataLevelCode::Topped) | ||||||
|          { |          { | ||||||
|             // Level has associated data level code
 |             // Level has associated data level code
 | ||||||
|             std::string codeName = wsr88d::GetDataLevelCodeName(code.value()); |             std::string codeName = wsr88d::GetDataLevelCodeName(code.value()); | ||||||
|  | @ -391,6 +392,7 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|             // Level has associated data value
 |             // Level has associated data value
 | ||||||
|             float       f = value.value(); |             float       f = value.value(); | ||||||
|             std::string units {}; |             std::string units {}; | ||||||
|  |             std::string suffix {}; | ||||||
|             std::string hoverText; |             std::string hoverText; | ||||||
| 
 | 
 | ||||||
|             std::shared_ptr<common::ColorTable> colorTable = |             std::shared_ptr<common::ColorTable> colorTable = | ||||||
|  | @ -403,6 +405,13 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|                units = colorTable->units(); |                units = colorTable->units(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             if (code.has_value() && | ||||||
|  |                 code.value() == wsr88d::DataLevelCode::Topped) | ||||||
|  |             { | ||||||
|  |                // Show " TOPPED" suffix for echo tops
 | ||||||
|  |                suffix = " TOPPED"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if (units.empty() ||          //
 |             if (units.empty() ||          //
 | ||||||
|                 units.starts_with("?") || //
 |                 units.starts_with("?") || //
 | ||||||
|                 boost::iequals(units, "NONE") || |                 boost::iequals(units, "NONE") || | ||||||
|  | @ -411,17 +420,17 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|             { |             { | ||||||
|                // Don't display a units value that wasn't intended to be
 |                // Don't display a units value that wasn't intended to be
 | ||||||
|                // displayed
 |                // displayed
 | ||||||
|                hoverText = fmt::format("{}", f); |                hoverText = fmt::format("{}{}", f, suffix); | ||||||
|             } |             } | ||||||
|             else if (std::isalpha(units.at(0))) |             else if (std::isalpha(units.at(0))) | ||||||
|             { |             { | ||||||
|                // dBZ, Kts, etc.
 |                // dBZ, Kts, etc.
 | ||||||
|                hoverText = fmt::format("{} {}", f, units); |                hoverText = fmt::format("{} {}{}", f, units, suffix); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                // %, etc.
 |                // %, etc.
 | ||||||
|                hoverText = fmt::format("{}{}", f, units); |                hoverText = fmt::format("{}{}{}", f, units, suffix); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Show the tooltip
 |             // Show the tooltip
 | ||||||
|  |  | ||||||
|  | @ -48,6 +48,7 @@ enum class Level3ProductCategory | ||||||
|    SpecificDifferentialPhase, |    SpecificDifferentialPhase, | ||||||
|    CorrelationCoefficient, |    CorrelationCoefficient, | ||||||
|    VerticallyIntegratedLiquid, |    VerticallyIntegratedLiquid, | ||||||
|  |    EchoTops, | ||||||
|    HydrometeorClassification, |    HydrometeorClassification, | ||||||
|    PrecipitationAccumulation, |    PrecipitationAccumulation, | ||||||
|    Unknown |    Unknown | ||||||
|  |  | ||||||
|  | @ -70,6 +70,9 @@ public: | ||||||
|    float         log_offset() const; |    float         log_offset() const; | ||||||
|    float         log_scale() const; |    float         log_scale() const; | ||||||
| 
 | 
 | ||||||
|  |    std::uint8_t data_mask() const; | ||||||
|  |    std::uint8_t topped_mask() const; | ||||||
|  | 
 | ||||||
|    units::angle::degrees<double> elevation() const; |    units::angle::degrees<double> elevation() const; | ||||||
| 
 | 
 | ||||||
|    bool IsCompressionEnabled() const; |    bool IsCompressionEnabled() const; | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ enum class DataLevelCode | ||||||
|    NoAccumulation, |    NoAccumulation, | ||||||
|    RangeFolded, |    RangeFolded, | ||||||
|    Reserved, |    Reserved, | ||||||
|  |    Topped, | ||||||
| 
 | 
 | ||||||
|    // Hydrometeor Classification
 |    // Hydrometeor Classification
 | ||||||
|    Biological, |    Biological, | ||||||
|  |  | ||||||
|  | @ -43,17 +43,19 @@ static const std::unordered_map<Level2Product, std::string> level2Palette_ { | ||||||
|    {Level2Product::Unknown, "???"}}; |    {Level2Product::Unknown, "???"}}; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<int, std::string> level3ProductCodeMap_ { | static const std::unordered_map<int, std::string> level3ProductCodeMap_ { | ||||||
|    {30, "SW"},   {37, "NCR"},  {56, "SRM"},  {57, "NVL"},  {78, "N1P"}, |    {30, "SW"},   {37, "NCR"},  {41, "NET"},  {56, "SRM"},  {57, "NVL"}, | ||||||
|    {79, "N3P"},  {80, "NTP"},  {81, "DPA"},  {82, "SPD"},  {94, "DR"}, |    {78, "N1P"},  {79, "N3P"},  {80, "NTP"},  {81, "DPA"},  {82, "SPD"}, | ||||||
|    {99, "DV"},   {134, "DVL"}, {138, "DSP"}, {153, "SDR"}, {154, "SDV"}, |    {94, "DR"},   {99, "DV"},   {134, "DVL"}, {135, "EET"}, {138, "DSP"}, | ||||||
|    {159, "DZD"}, {161, "DCC"}, {163, "DKD"}, {165, "DHC"}, {166, "ML"}, |    {153, "SDR"}, {154, "SDV"}, {159, "DZD"}, {161, "DCC"}, {163, "DKD"}, | ||||||
|    {169, "OHA"}, {170, "DAA"}, {172, "DTA"}, {173, "DUA"}, {174, "DOD"}, |    {165, "DHC"}, {166, "ML"},  {169, "OHA"}, {170, "DAA"}, {172, "DTA"}, | ||||||
|    {175, "DSD"}, {177, "HHC"}, {180, "TDR"}, {182, "TDV"}}; |    {173, "DUA"}, {174, "DOD"}, {175, "DSD"}, {177, "HHC"}, {180, "TDR"}, | ||||||
|  |    {182, "TDV"}}; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<std::string, std::string> | static const std::unordered_map<std::string, std::string> | ||||||
|    level3ProductDescription_ { |    level3ProductDescription_ { | ||||||
|       {"SW", "Spectrum Width"}, |       {"SW", "Spectrum Width"}, | ||||||
|       {"NCR", "Composite Reflectivity"}, |       {"NCR", "Composite Reflectivity"}, | ||||||
|  |       {"NET", "Echo Tops"}, | ||||||
|       {"SRM", "Storm Relative Mean Radial Velocity"}, |       {"SRM", "Storm Relative Mean Radial Velocity"}, | ||||||
|       {"NVL", "Vertically Integrated Liquid"}, |       {"NVL", "Vertically Integrated Liquid"}, | ||||||
|       {"N1P", "Surface Rainfall Accumulation (1 hr)"}, |       {"N1P", "Surface Rainfall Accumulation (1 hr)"}, | ||||||
|  | @ -64,6 +66,7 @@ static const std::unordered_map<std::string, std::string> | ||||||
|       {"DR", "Digital Reflectivity"}, |       {"DR", "Digital Reflectivity"}, | ||||||
|       {"DV", "Digital Velocity"}, |       {"DV", "Digital Velocity"}, | ||||||
|       {"DVL", "Digital Vertically Integrated Liquid"}, |       {"DVL", "Digital Vertically Integrated Liquid"}, | ||||||
|  |       {"EET", "Enhanced Echo Tops"}, | ||||||
|       {"DSP", "Digital Storm Total Precipitation"}, |       {"DSP", "Digital Storm Total Precipitation"}, | ||||||
|       {"SDR", "Super-Resolution Reflectivity"}, |       {"SDR", "Super-Resolution Reflectivity"}, | ||||||
|       {"SDV", "Super-Resolution Velocity"}, |       {"SDV", "Super-Resolution Velocity"}, | ||||||
|  | @ -115,6 +118,10 @@ static const std::unordered_map<std::string, std::vector<std::string>> | ||||||
|       {"DVL", {"DVL"}}, |       {"DVL", {"DVL"}}, | ||||||
|       {"NVL", {"NVL"}}, |       {"NVL", {"NVL"}}, | ||||||
| 
 | 
 | ||||||
|  |       // Echo Tops
 | ||||||
|  |       {"EET", {"EET"}}, | ||||||
|  |       {"NET", {"NET"}}, | ||||||
|  | 
 | ||||||
|       // Hydrometeor Classification
 |       // Hydrometeor Classification
 | ||||||
|       {"DHC", {"NXH", "NYH", "NZH", "N0H", "NAH", "N1H", "NBH", "N2H", "N3H"}}, |       {"DHC", {"NXH", "NYH", "NZH", "N0H", "NAH", "N1H", "NBH", "N2H", "N3H"}}, | ||||||
|       {"HHC", {"HHC"}}, |       {"HHC", {"HHC"}}, | ||||||
|  | @ -149,6 +156,7 @@ static const std::unordered_map<Level3ProductCategory, std::string> | ||||||
|       {Level3ProductCategory::SpecificDifferentialPhase, "KDP"}, |       {Level3ProductCategory::SpecificDifferentialPhase, "KDP"}, | ||||||
|       {Level3ProductCategory::CorrelationCoefficient, "CC"}, |       {Level3ProductCategory::CorrelationCoefficient, "CC"}, | ||||||
|       {Level3ProductCategory::VerticallyIntegratedLiquid, "VIL"}, |       {Level3ProductCategory::VerticallyIntegratedLiquid, "VIL"}, | ||||||
|  |       {Level3ProductCategory::EchoTops, "ET"}, | ||||||
|       {Level3ProductCategory::HydrometeorClassification, "HC"}, |       {Level3ProductCategory::HydrometeorClassification, "HC"}, | ||||||
|       {Level3ProductCategory::PrecipitationAccumulation, "ACC"}, |       {Level3ProductCategory::PrecipitationAccumulation, "ACC"}, | ||||||
|       {Level3ProductCategory::Unknown, "?"}}; |       {Level3ProductCategory::Unknown, "?"}}; | ||||||
|  | @ -167,6 +175,7 @@ static const std::unordered_map<Level3ProductCategory, std::string> | ||||||
|        "Correlation Coefficient"}, |        "Correlation Coefficient"}, | ||||||
|       {Level3ProductCategory::VerticallyIntegratedLiquid, |       {Level3ProductCategory::VerticallyIntegratedLiquid, | ||||||
|        "Vertically Integrated Liquid"}, |        "Vertically Integrated Liquid"}, | ||||||
|  |       {Level3ProductCategory::EchoTops, "Echo Tops"}, | ||||||
|       {Level3ProductCategory::HydrometeorClassification, |       {Level3ProductCategory::HydrometeorClassification, | ||||||
|        "Hydrometeor Classification"}, |        "Hydrometeor Classification"}, | ||||||
|       {Level3ProductCategory::PrecipitationAccumulation, |       {Level3ProductCategory::PrecipitationAccumulation, | ||||||
|  | @ -183,6 +192,7 @@ static const std::unordered_map<Level3ProductCategory, std::vector<std::string>> | ||||||
|       {Level3ProductCategory::SpecificDifferentialPhase, {"DKD"}}, |       {Level3ProductCategory::SpecificDifferentialPhase, {"DKD"}}, | ||||||
|       {Level3ProductCategory::CorrelationCoefficient, {"DCC"}}, |       {Level3ProductCategory::CorrelationCoefficient, {"DCC"}}, | ||||||
|       {Level3ProductCategory::VerticallyIntegratedLiquid, {"DVL", "NVL"}}, |       {Level3ProductCategory::VerticallyIntegratedLiquid, {"DVL", "NVL"}}, | ||||||
|  |       {Level3ProductCategory::EchoTops, {"EET", "NET"}}, | ||||||
|       {Level3ProductCategory::HydrometeorClassification, {"DHC", "HHC"}}, |       {Level3ProductCategory::HydrometeorClassification, {"DHC", "HHC"}}, | ||||||
|       {Level3ProductCategory::PrecipitationAccumulation, {"DAA", "DTA", "DUA"}}, |       {Level3ProductCategory::PrecipitationAccumulation, {"DAA", "DTA", "DUA"}}, | ||||||
|       {Level3ProductCategory::Unknown, {}}}; |       {Level3ProductCategory::Unknown, {}}}; | ||||||
|  | @ -197,6 +207,7 @@ static const std::unordered_map<Level3ProductCategory, std::string> | ||||||
|       {Level3ProductCategory::SpecificDifferentialPhase, "N0K"}, |       {Level3ProductCategory::SpecificDifferentialPhase, "N0K"}, | ||||||
|       {Level3ProductCategory::CorrelationCoefficient, "N0C"}, |       {Level3ProductCategory::CorrelationCoefficient, "N0C"}, | ||||||
|       {Level3ProductCategory::VerticallyIntegratedLiquid, "DVL"}, |       {Level3ProductCategory::VerticallyIntegratedLiquid, "DVL"}, | ||||||
|  |       {Level3ProductCategory::EchoTops, "EET"}, | ||||||
|       {Level3ProductCategory::HydrometeorClassification, "N0H"}, |       {Level3ProductCategory::HydrometeorClassification, "N0H"}, | ||||||
|       {Level3ProductCategory::PrecipitationAccumulation, "DAA"}}; |       {Level3ProductCategory::PrecipitationAccumulation, "DAA"}}; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -370,6 +370,9 @@ uint16_t ProductDescriptionBlock::threshold() const | ||||||
|    case 177: |    case 177: | ||||||
|       threshold = 10; |       threshold = 10; | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return threshold; |    return threshold; | ||||||
|  | @ -418,6 +421,9 @@ float ProductDescriptionBlock::offset() const | ||||||
|    case 176: |    case 176: | ||||||
|       offset = util::DecodeFloat32(p->halfword(33), p->halfword(34)); |       offset = util::DecodeFloat32(p->halfword(33), p->halfword(34)); | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return offset; |    return offset; | ||||||
|  | @ -473,6 +479,9 @@ float ProductDescriptionBlock::scale() const | ||||||
|    case 176: |    case 176: | ||||||
|       scale = util::DecodeFloat32(p->halfword(31), p->halfword(32)); |       scale = util::DecodeFloat32(p->halfword(31), p->halfword(32)); | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return scale; |    return scale; | ||||||
|  | @ -586,6 +595,9 @@ uint16_t ProductDescriptionBlock::number_of_levels() const | ||||||
|    case 179: |    case 179: | ||||||
|       numberOfLevels = 71; |       numberOfLevels = 71; | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return numberOfLevels; |    return numberOfLevels; | ||||||
|  | @ -600,6 +612,9 @@ std::uint16_t ProductDescriptionBlock::log_start() const | ||||||
|    case 134: |    case 134: | ||||||
|       logStart = p->halfword(33); |       logStart = p->halfword(33); | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return logStart; |    return logStart; | ||||||
|  | @ -614,6 +629,9 @@ float ProductDescriptionBlock::log_offset() const | ||||||
|    case 134: |    case 134: | ||||||
|       logOffset = util::DecodeFloat16(p->halfword(35)); |       logOffset = util::DecodeFloat16(p->halfword(35)); | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return logOffset; |    return logOffset; | ||||||
|  | @ -628,11 +646,48 @@ float ProductDescriptionBlock::log_scale() const | ||||||
|    case 134: |    case 134: | ||||||
|       logScale = util::DecodeFloat16(p->halfword(34)); |       logScale = util::DecodeFloat16(p->halfword(34)); | ||||||
|       break; |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return logScale; |    return logScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::uint8_t ProductDescriptionBlock::data_mask() const | ||||||
|  | { | ||||||
|  |    std::uint8_t dataMask = 0xff; | ||||||
|  | 
 | ||||||
|  |    switch (p->productCode_) | ||||||
|  |    { | ||||||
|  |    case 135: | ||||||
|  |       dataMask = static_cast<std::uint8_t>(p->halfword(31)); | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return dataMask; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint8_t ProductDescriptionBlock::topped_mask() const | ||||||
|  | { | ||||||
|  |    std::uint8_t toppedMask = 0x00; | ||||||
|  | 
 | ||||||
|  |    switch (p->productCode_) | ||||||
|  |    { | ||||||
|  |    case 135: | ||||||
|  |       toppedMask = static_cast<std::uint8_t>(p->halfword(34)); | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return toppedMask; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| units::angle::degrees<double> ProductDescriptionBlock::elevation() const | units::angle::degrees<double> ProductDescriptionBlock::elevation() const | ||||||
| { | { | ||||||
|    double elevation = 0.0; |    double elevation = 0.0; | ||||||
|  | @ -816,6 +871,10 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
|       case 1: |       case 1: | ||||||
|          return DataLevelCode::BadData; |          return DataLevelCode::BadData; | ||||||
|       default: |       default: | ||||||
|  |          if (level & topped_mask()) | ||||||
|  |          { | ||||||
|  |             return DataLevelCode::Topped; | ||||||
|  |          } | ||||||
|          break; |          break; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|  | @ -864,6 +923,8 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
|          return DataLevelCode::UnknownClassification; |          return DataLevelCode::UnknownClassification; | ||||||
|       case 150: |       case 150: | ||||||
|          return DataLevelCode::RangeFolded; |          return DataLevelCode::RangeFolded; | ||||||
|  |       default: | ||||||
|  |          break; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|  | @ -1032,6 +1093,10 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const | ||||||
|          } |          } | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|  |       case 135: | ||||||
|  |          level = level & data_mask(); | ||||||
|  |          [[fallthrough]]; | ||||||
|  | 
 | ||||||
|       default: |       default: | ||||||
|          f = level * dataScale + dataOffset; |          f = level * dataScale + dataOffset; | ||||||
|          break; |          break; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat