public override void Parse(DecodedMetar decodedMetar) { var visibility = new StringBuilder(); if (decodedMetar.Cavok) { visibility.Append($"{strings.VisibilityCAVOK}"); } else if (decodedMetar.Visibility?.PrevailingVisibility != null) { if (Math.Round(decodedMetar.Visibility.PrevailingVisibility.GetConvertedValue(Value.Unit.Meter)) == 9999) { visibility.Append($"{strings.Visibility10KmOrMore}"); } else { visibility.Append( StringTemplate.Format( strings.PrevailingVisibility, new { prevailingVisibility = decodedMetar.Visibility.PrevailingVisibility.GetConvertedValue(Value.Unit.Meter) }, false)); } } Label = strings.VisibilityLabel; Message = visibility.ToString(); }
private static string OutputHtmlTable(this DecodedMetar decodedMetar, string tableClass = "", bool showRawMetar = false) { var weatherMessageSb = new StringBuilder(); if (string.IsNullOrEmpty(tableClass)) { weatherMessageSb.Append($"<table>\n"); } else { weatherMessageSb.Append($"<table class=\"{tableClass}\">\n"); } if (showRawMetar) { var rawMetarMetadata = new RawMetarMetadata(); rawMetarMetadata.Parse(decodedMetar); weatherMessageSb.Append(rawMetarMetadata.ToHtmlTableRow()); } foreach (var metadata in _defaultMetadataToDisplay) { metadata.Parse(decodedMetar); weatherMessageSb.Append(metadata.ToHtmlTableRow()); } weatherMessageSb.Append("</table>"); return(weatherMessageSb.ToString()); }
/// <inheritdoc/> public override void Parse(DecodedMetar decodedMetar) { var clouds = new StringBuilder(); var subWeatherMessageSb = new StringBuilder(); if (decodedMetar.Clouds?.Count > 0) { clouds.Append(string.Join(", ", decodedMetar.Clouds.Select(cloud => { subWeatherMessageSb.Clear(); var cloudAmount = CloudsAmount.ContainsKey(cloud.Amount.ToString()) ? CloudsAmount[cloud.Amount.ToString()] : string.Empty; var cloudType = CloudsType.ContainsKey(cloud.Type.ToString()) ? CloudsType[cloud.Type.ToString()] : string.Empty; subWeatherMessageSb.Append($"{cloudAmount}{(cloud.Type != CloudLayer.CloudType.NULL ? string.Concat(" ", cloudType) : string.Empty)} "); if (cloud.BaseHeight != null) { subWeatherMessageSb.Append( StringTemplate.Format( strings.CloudsDetails, new { feet = Math.Round(cloud.BaseHeight.GetConvertedValue(Value.Unit.Feet)), meters = Math.Round(cloud.BaseHeight.GetConvertedValue(Value.Unit.Meter)) }, false)); } return(subWeatherMessageSb); }))); } Label = strings.CloudsLabel; Message = clouds.ToString(); }
/// <summary> /// Retrieves a beautified string output of a DecodedMetar /// </summary> /// <param name="decodedMetar">The decoded METAR.</param> public static string GetWeatherMessage(this DecodedMetar decodedMetar, OutputType outputType = OutputType.Text, bool showRawMetar = false, string htmlClass = "") { var weatherMessageSb = new StringBuilder(); if (!decodedMetar.IsValid) { weatherMessageSb.Append($"{decodedMetar.RawMetar}\n"); weatherMessageSb.Append($"{strings.MetarIsNotValid}:\n"); foreach (var metarChunkDecodedEx in decodedMetar.DecodingExceptions) { weatherMessageSb.Append($"{metarChunkDecodedEx.Message}\n"); } } else { switch (outputType) { case OutputType.Text: weatherMessageSb.Append(decodedMetar.OutputText(showRawMetar)); break; case OutputType.HtmlTable: weatherMessageSb.Append(decodedMetar.OutputHtmlTable(htmlClass, showRawMetar)); break; case OutputType.HtmlDiv: weatherMessageSb.Append(decodedMetar.OutputHtmlText(htmlClass, showRawMetar)); break; } } return(weatherMessageSb.ToString()); }
public override void Parse(DecodedMetar decodedMetar) { var wind = new StringBuilder(); if (decodedMetar.SurfaceWind != null) { if (decodedMetar.SurfaceWind.MeanDirection != null) { wind.Append(StringTemplate.Format(strings.WindDetails, new { meanDirectionDegrees = decodedMetar.SurfaceWind.MeanDirection.ActualValue, meanDirectionCardinal = decodedMetar.SurfaceWind.MeanDirection.ActualValue.ConvertDegreesToCardinal(false).ToLowerInvariant(), speedKnot = Math.Round(decodedMetar.SurfaceWind.MeanSpeed.GetConvertedValue(Value.Unit.Knot)), })); } // SurfaceWind.SpeedVariations property contains gust wind speed if (decodedMetar.SurfaceWind.SpeedVariations != null) { if (decodedMetar.SurfaceWind.MeanDirection != null) { wind.Append(", "); wind.Append($"{strings.WindWith} "); } wind.Append(StringTemplate.Format(strings.WindGusts, new { windGustsKnot = Math.Round(decodedMetar.SurfaceWind.SpeedVariations.GetConvertedValue(Value.Unit.Knot)) }, false)); } // SurfaceWind.VariableDirection property contains variable wind direction flag information (VRB) if (decodedMetar.SurfaceWind.VariableDirection) { wind.Append($" ({strings.WindVariableDirection})"); } else if (decodedMetar.SurfaceWind.DirectionVariations?.Length > 1 && decodedMetar.SurfaceWind.DirectionVariations[0] != null && decodedMetar.SurfaceWind.DirectionVariations[1] != null) { wind.Append(StringTemplate.Format(strings.WindDirectionVariations, new { windDirectionVariationMinDegrees = decodedMetar.SurfaceWind.DirectionVariations[0].ActualValue, windDirectionVariationMinCardinal = decodedMetar.SurfaceWind.DirectionVariations[0].ActualValue.ConvertDegreesToCardinal(false).ToLowerInvariant(), windDirectionVariationMaxDegrees = decodedMetar.SurfaceWind.DirectionVariations[1].ActualValue, windDirectionVariationMaxCardinal = decodedMetar.SurfaceWind.DirectionVariations[1].ActualValue.ConvertDegreesToCardinal(false).ToLowerInvariant(), }, false)); } } Label = strings.WindLabel; Message = wind.ToString(); }
/// <inheritdoc/> public override void Parse(DecodedMetar decodedMetar) { var pressure = new StringBuilder(); if (decodedMetar.Pressure != null) { pressure.Append( StringTemplate.Format( strings.PressureDetails, new { hectoPascal = Math.Round(decodedMetar.Pressure.GetConvertedValue(Value.Unit.HectoPascal)), mercuryInch = Math.Round(decodedMetar.Pressure.GetConvertedValue(Value.Unit.MercuryInch)) }, false)); } Label = strings.PressureLabel; Message = pressure.ToString(); }
private static string OutputText(this DecodedMetar decodedMetar, bool showRawMetar = false) { var weatherMessageSb = new StringBuilder(); if (showRawMetar) { var rawMetarMetadata = new RawMetarMetadata(); rawMetarMetadata.Parse(decodedMetar); weatherMessageSb.Append(rawMetarMetadata.ToString()); } foreach (var metadata in _defaultMetadataToDisplay) { metadata.Parse(decodedMetar); weatherMessageSb.Append(metadata.ToString()); } return(weatherMessageSb.ToString()); }
/// <inheritdoc/> public override void Parse(DecodedMetar decodedMetar) { var temperatures = new StringBuilder(); if (decodedMetar.AirTemperature != null) { // For temperatures, original unit is degree Celsius temperatures.Append( StringTemplate.Format( strings.TemperaturesDetails, new { airTemperatureC = decodedMetar.AirTemperature.ActualValue, airTemperatureF = decodedMetar.AirTemperature.ActualValue.ConvertCelsiusToFahrenheit(), dewTemperatureC = decodedMetar.DewPointTemperature.ActualValue, dewTemperatureF = decodedMetar.DewPointTemperature.ActualValue.ConvertCelsiusToFahrenheit(), }, false)); } Label = strings.TemperaturesLabel; Message = temperatures.ToString(); }
/// <inheritdoc/> public override void Parse(DecodedMetar decodedMetar) { var observationDate = new StringBuilder(); string sMetarDay = decodedMetar.Day.ToString(); string sMetarTime = new Regex(@"\d{2}:\d{2}").Match(decodedMetar.Time).Value; observationDate.Append(StringTemplate.Format(strings.ObservationDetails, new { metarDay = sMetarDay, metarTime = sMetarTime, }, false)); if (decodedMetar.Status == "AUTO") { observationDate.Append(", "); observationDate.Append($"{strings.AutomatedObservation}"); } Label = strings.ObservationDateLabel; Message = observationDate.ToString(); }
public override void Parse(DecodedMetar decodedMetar) { var windshear = new StringBuilder(); if (decodedMetar.WindshearAllRunways ?? false) { windshear.Append($"{strings.WindshearAllRunways} "); } else if (decodedMetar.WindshearRunways?.Count > 0) { windshear.Append(string.Join(", ", decodedMetar.WindshearRunways.Select(windshearRunway => StringTemplate.Format(strings.WindshearOnRunway, new { wr = windshearRunway } ) ))); } Label = strings.WindshearLabel; Message = windshear.ToString(); }
public override void Parse(DecodedMetar decodedMetar) { var visualRange = new StringBuilder(); var subWeatherMessageSb = new StringBuilder(); if (decodedMetar.RunwaysVisualRange?.Count > 0) { visualRange.Append(string.Join(", ", decodedMetar.RunwaysVisualRange.Select(rvr => { subWeatherMessageSb.Clear(); subWeatherMessageSb.Append(StringTemplate.Format($"{strings.VisualRangeForRunway} : ", new { runway = rvr.Runway }, false)); var visualRangeMin = rvr.VisualRangeInterval?.Length > 0 ? (float?)Math.Round(rvr.VisualRangeInterval[0].GetConvertedValue(Value.Unit.Meter)) : null; if (visualRangeMin == null) { visualRangeMin = rvr.VisualRange != null ? (float?)Math.Round(rvr.VisualRange.GetConvertedValue(Value.Unit.Meter)) : null; } var visualRangeMax = rvr.VisualRangeInterval?.Length > 1 ? (float?)Math.Round(rvr.VisualRangeInterval[1].GetConvertedValue(Value.Unit.Meter)) : null; if (visualRangeMax == null) { subWeatherMessageSb.Append(StringTemplate.Format(strings.VisualRangeExact + " ", new { visualRangeMin = visualRangeMin }, false)); } else { subWeatherMessageSb.Append(StringTemplate.Format(strings.VisualRangeBetween + " ", new { visualRangeMin = visualRangeMin, visualRangeMax = visualRangeMax }, false)); } switch (rvr.PastTendency) { case RunwayVisualRange.Tendency.U: subWeatherMessageSb.Append($"({strings.UpwardTrend}) "); break; case RunwayVisualRange.Tendency.D: subWeatherMessageSb.Append($"({strings.DownwardTrend}) "); break; case RunwayVisualRange.Tendency.NONE: break; case RunwayVisualRange.Tendency.N: break; default: throw new ArgumentOutOfRangeException(); } return(subWeatherMessageSb); }))); } Label = strings.VisualRangeLabel; Message = visualRange.ToString(); }
/// <summary> /// Decode a full metar string into a complete metar object. /// </summary> /// <param name="rawMetar"></param> /// <returns></returns> public static DecodedMetar ParseWithMode(string rawMetar, bool isStrict = false) { // prepare decoding inputs/outputs: (upper case, trim, // remove 'end of message', no more than one space) var cleanMetar = rawMetar.ToUpper().Trim(); cleanMetar = Regex.Replace(cleanMetar, "=$", string.Empty); cleanMetar = Regex.Replace(cleanMetar, "[ ]{2,}", " ") + " "; var remainingMetar = cleanMetar; var decodedMetar = new DecodedMetar(cleanMetar); var withCavok = false; // call each decoder in the chain and use results to populate decoded metar foreach (var chunkDecoder in _decoderChain) { try { // try to parse a chunk with current chunk decoder var decodedData = TryParsing(chunkDecoder, isStrict, remainingMetar, withCavok); // log any exception that would have occur at primary decoding if (decodedData.ContainsKey(ExceptionKey)) { decodedMetar.AddDecodingException((MetarChunkDecoderException)decodedData[ExceptionKey]); } // map obtained fields (if any) to the final decoded object if (decodedData.ContainsKey(ResultKey) && decodedData[ResultKey] is Dictionary <string, object> ) { var result = decodedData[ResultKey] as Dictionary <string, object>; foreach (var obj in result) { if (obj.Value != null) { typeof(DecodedMetar).GetProperty(obj.Key).SetValue(decodedMetar, obj.Value); } } } // update remaining metar for next round remainingMetar = decodedData[RemainingMetarKey] as string; } catch (MetarChunkDecoderException metarChunkDecoderException) { // log error in decoded metar decodedMetar.AddDecodingException(metarChunkDecoderException); // abort decoding if strict mode is activated, continue otherwise if (isStrict) { break; } // update remaining metar for next round remainingMetar = metarChunkDecoderException.RemainingMetar; } // hook for report status decoder, abort if nil, but decoded metar is valid though if (chunkDecoder is ReportStatusChunkDecoder && decodedMetar.Status == "NIL") { break; } // hook for CAVOK decoder, keep CAVOK information in memory if (chunkDecoder is VisibilityChunkDecoder) { withCavok = decodedMetar.Cavok; } } return(decodedMetar); }
/// <summary> /// Prepares the Label and Message for use /// </summary> /// <param name="decodedMetar"></param> public abstract void Parse(DecodedMetar decodedMetar);
/// <inheritdoc/> public override void Parse(DecodedMetar decodedMetar) { Label = strings.RawMetarLabel; Message = decodedMetar.RawMetar; }