Exemple #1
0
        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();
        }
Exemple #2
0
        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());
        }
Exemple #3
0
        /// <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();
        }
Exemple #4
0
        /// <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();
        }
Exemple #6
0
        /// <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();
        }
Exemple #7
0
        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();
        }
Exemple #9
0
        /// <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();
        }
Exemple #10
0
        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();
        }
Exemple #11
0
        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);
Exemple #14
0
 /// <inheritdoc/>
 public override void Parse(DecodedMetar decodedMetar)
 {
     Label   = strings.RawMetarLabel;
     Message = decodedMetar.RawMetar;
 }