-
1
require 'metar'
-
1
require 'time'
-
-
1
TEST_METAR1 = "2023-09-12 23:30:00\nKJFK 131751Z 22015KT 10SM FEW040 SCT100 23/16 A2992 RMK AO2 SLP132 T02330156 10233 20194 58005"
-
1
TEST_METAR = "2023-09-12 23:30:00\nUUEE 122330Z 08003MPS 9000 NSC 08/08 Q1022 R06C/CLRD62 NOSIG"
-
-
1
class String
-
1
def underscore
-
5
self.gsub(/::/, '/').
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
-
tr("-", "_").
-
downcase
-
end
-
end
-
5
class Array; def represent = map{ _1.represent } end
-
5
class Array; def to_s = map{ _1.to_s }.join ', ' end
-
2
class String; def represent = to_s end
-
2
class Symbol; def represent = to_s end
-
2
class String; def raw = to_s end
-
2
class Struct; def represent
-
{ self.class.to_s[/([^:]+)$/,1].underscore.to_sym => to_h.transform_values { _1.respond_to?(:represent) ? _1.represent : _1 } }
-
end
-
end
-
-
1
module Metar::Data
-
2
class Temperature; def represent = { degrees: to_degrees, kelvin: to_kelvin, fahrenheit: to_fahrenheit, to_s: } end
-
2
class Wind; def represent = { direction: direction&.represent, speed: speed&.represent, gusts: gusts&.represent, to_s: } end
-
2
class VariableWind; def represent = { direction1: , direction2:, to_s: } end
-
2
class Direction; def represent = { degrees: to_degrees, compass: to_compass, to_s: } end
-
2
class Speed; def represent = { meters: to_meters_per_second, knots: to_knots, to_s: } end
-
2
class SkyCondition; def represent = { summary: to_summary, height: height&.represent, type:, quantity:, to_s: } end
-
2
class SkyCondition; def to_s = to_summary end
-
2
class SkyConditions; def to_s = map(&:to_s).join ' ' end
-
2
class Pressure; def represent = pressure.represent end
-
2
class Pressure; def to_s = pressure.to_s end
-
2
class M9t::Pressure; def represent = { inches_of_mercury: to_inches_of_mercury, bar: to_bar, pascals: to_pascals, hectopascals: to_hectopascals, kilopascals: to_kilopascals, to_s: } end
-
2
class M9t::Distance; def represent = { meters: to_meters, kilometers: to_kilometers, feet: to_feet, miles: to_miles, to_s: } end
-
2
class M9t::Direction; def represent = { degrees: to_degrees, compass: to_compass, to_s: } end
-
2
class WeatherPhenomenon; def represent = to_s end
-
2
class Observer; def represent = { value: } end
-
2
class Observer; def to_s = value.to_s end
-
2
class Visibility; def represent = { distance: distance.represent, direction: direction&.represent, comparator: comparator, to_s:} end
-
2
class Distance; def represent = { meters: to_meters, kilometers: to_kilometers, feet: to_feet, miles: to_miles, to_s: } end
-
2
class RunwayVisibleRange; def represent = to_s end
-
end
-
-
1
class Parser
-
1
def initialize(date, msg)
-
2
raw = Metar::Raw::Data.new(msg, DateTime.parse(date))
-
2
@parser = Metar::Parser.new(raw)
-
end
-
-
1
def summary
-
2
to_s = self.metar :to_s
-
50
to_s.reject{ _2.nil? || _2.to_s.empty? }.map{ "#{_1}: #{_2}"}.join ', '
-
end
-
-
1
def metar(method = :represent)
-
4
@parser.instance_eval do
-
4
attr = { datetime: time } # station_code: station_code, #metar: metar,
-
4
%i( minimum_visibility observer sea_level_pressure temperature dew_point visibility variable_wind vertical_visibility wind
-
present_weather recent_weather runway_visible_range sky_conditions remarks)
-
.each do |key|
-
56
attr[key] = self.send(key)&.send(method)
-
end
-
4
attr[:cavok] = 'CAVOK' if cavok?
-
4
attr
-
end
-
end
-
end
-
-
# SELF TEST ============================================================================================================
-
1
if File.expand_path($0) == File.expand_path(__FILE__)
-
require 'rbase/rest_client_faraday'
-
-
# Metar::Parse.compliance = :strict
-
parser = Parser.new *TEST_METAR1.lines
-
p parser.metar
-
-
require_relative 'sources'
-
metartaf = Sources.first code: 'UUBW'
-
parser = Parser.new Time.now.utc.iso8601, metartaf[:metar]
-
p parser.summary
-
end