metar-parser 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/metar/data/base.rb +15 -0
- data/lib/metar/data/density_altitude.rb +15 -0
- data/lib/metar/data/direction.rb +9 -0
- data/lib/metar/data/distance.rb +27 -0
- data/lib/metar/data/lightning.rb +61 -0
- data/lib/metar/data/observer.rb +24 -0
- data/lib/metar/data/pressure.rb +23 -0
- data/lib/metar/data/remark.rb +98 -0
- data/lib/metar/data/runway_visible_range.rb +85 -0
- data/lib/metar/data/sky_condition.rb +61 -0
- data/lib/metar/data/speed.rb +22 -0
- data/lib/metar/data/station_code.rb +7 -0
- data/lib/metar/data/temperature.rb +21 -0
- data/lib/metar/data/temperature_and_dew_point.rb +18 -0
- data/lib/metar/data/time.rb +54 -0
- data/lib/metar/data/variable_wind.rb +25 -0
- data/lib/metar/data/vertical_visibility.rb +26 -0
- data/lib/metar/data/visibility.rb +71 -0
- data/lib/metar/data/visibility_remark.rb +8 -0
- data/lib/metar/data/weather_phenomenon.rb +86 -0
- data/lib/metar/data/wind.rb +82 -0
- data/lib/metar/data.rb +22 -636
- data/lib/metar/i18n.rb +6 -0
- data/lib/metar/parser.rb +165 -120
- data/lib/metar/report.rb +1 -1
- data/lib/metar/version.rb +2 -2
- data/lib/metar.rb +7 -6
- data/locales/de.yml +1 -0
- data/locales/en.yml +1 -0
- data/locales/it.yml +2 -1
- data/locales/pt-BR.yml +1 -0
- data/spec/data/density_altitude_spec.rb +12 -0
- data/spec/{distance_spec.rb → data/distance_spec.rb} +1 -1
- data/spec/data/lightning_spec.rb +49 -0
- data/spec/data/pressure_spec.rb +22 -0
- data/spec/data/remark_spec.rb +99 -0
- data/spec/data/runway_visible_range_spec.rb +92 -0
- data/spec/{sky_condition_spec.rb → data/sky_condition_spec.rb} +10 -6
- data/spec/data/speed_spec.rb +45 -0
- data/spec/data/temperature_spec.rb +36 -0
- data/spec/{variable_wind_spec.rb → data/variable_wind_spec.rb} +6 -6
- data/spec/{vertical_visibility_spec.rb → data/vertical_visibility_spec.rb} +2 -2
- data/spec/{data_spec.rb → data/visibility_remark_spec.rb} +1 -11
- data/spec/{visibility_spec.rb → data/visibility_spec.rb} +9 -7
- data/spec/{weather_phenomenon_spec.rb → data/weather_phenomenon_spec.rb} +7 -3
- data/spec/{wind_spec.rb → data/wind_spec.rb} +10 -7
- data/spec/parser_spec.rb +107 -13
- data/spec/report_spec.rb +12 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/station_spec.rb +2 -1
- metadata +56 -31
- data/spec/pressure_spec.rb +0 -22
- data/spec/remark_spec.rb +0 -147
- data/spec/runway_visible_range_spec.rb +0 -81
- data/spec/speed_spec.rb +0 -45
- data/spec/temperature_spec.rb +0 -36
@@ -0,0 +1,8 @@
|
|
1
|
+
class Metar::Data::VisibilityRemark < Metar::Data::Visibility
|
2
|
+
def self.parse(raw)
|
3
|
+
metres, direction = raw.scan(/^(\d{4})([NESW]?)$/)[0]
|
4
|
+
distance = Metar::Data::Distance.new(metres)
|
5
|
+
|
6
|
+
new(raw, distance: distance, direction: direction, comparator: :more_than)
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "metar/i18n"
|
2
|
+
|
3
|
+
class Metar::Data::WeatherPhenomenon < Metar::Data::Base
|
4
|
+
Modifiers = {
|
5
|
+
'+' => 'heavy',
|
6
|
+
'-' => 'light',
|
7
|
+
'VC' => 'nearby',
|
8
|
+
'-VC' => 'nearby light',
|
9
|
+
'+VC' => 'nearby heavy',
|
10
|
+
}
|
11
|
+
|
12
|
+
Descriptors = {
|
13
|
+
'BC' => 'patches of',
|
14
|
+
'BL' => 'blowing',
|
15
|
+
'DR' => 'low drifting',
|
16
|
+
'FZ' => 'freezing',
|
17
|
+
'MI' => 'shallow',
|
18
|
+
'PR' => 'partial',
|
19
|
+
'SH' => 'shower of',
|
20
|
+
'TS' => 'thunderstorm and',
|
21
|
+
}
|
22
|
+
|
23
|
+
Phenomena = {
|
24
|
+
'BR' => 'mist',
|
25
|
+
'DU' => 'dust',
|
26
|
+
'DZ' => 'drizzle',
|
27
|
+
'FG' => 'fog',
|
28
|
+
'FU' => 'smoke',
|
29
|
+
'GR' => 'hail',
|
30
|
+
'GS' => 'small hail',
|
31
|
+
'HZ' => 'haze',
|
32
|
+
'IC' => 'ice crystals',
|
33
|
+
'PL' => 'ice pellets',
|
34
|
+
'PO' => 'dust whirls',
|
35
|
+
'PY' => 'spray', # US only
|
36
|
+
'RA' => 'rain',
|
37
|
+
'SA' => 'sand',
|
38
|
+
'SH' => 'shower',
|
39
|
+
'SN' => 'snow',
|
40
|
+
'SG' => 'snow grains',
|
41
|
+
'SQ' => 'squall',
|
42
|
+
'UP' => 'unknown phenomenon', # => AUTO
|
43
|
+
'VA' => 'volcanic ash',
|
44
|
+
'FC' => 'funnel cloud',
|
45
|
+
'SS' => 'sand storm',
|
46
|
+
'DS' => 'dust storm',
|
47
|
+
'TS' => 'thunderstorm',
|
48
|
+
}
|
49
|
+
|
50
|
+
# Accepts all standard (and some non-standard) present weather codes
|
51
|
+
def self.parse(raw)
|
52
|
+
phenomena = Phenomena.keys.join('|')
|
53
|
+
descriptors = Descriptors.keys.join('|')
|
54
|
+
modifiers = Modifiers.keys.join('|')
|
55
|
+
modifiers.gsub!(/([\+\-])/) { "\\#$1" }
|
56
|
+
rxp = Regexp.new("^(RE)?(#{modifiers})?(#{descriptors})?((?:#{phenomena}){1,2})$")
|
57
|
+
m = rxp.match(raw)
|
58
|
+
return nil if m.nil?
|
59
|
+
|
60
|
+
recent = m[1] == "RE"
|
61
|
+
modifier_code = m[2]
|
62
|
+
descriptor_code = m[3]
|
63
|
+
phenomena_codes = m[4].scan(/../)
|
64
|
+
phenomena_phrase = phenomena_codes.map { |c| Phenomena[c] }.join(' and ')
|
65
|
+
|
66
|
+
new(
|
67
|
+
raw,
|
68
|
+
phenomenon: phenomena_phrase,
|
69
|
+
modifier: Modifiers[modifier_code],
|
70
|
+
descriptor: Descriptors[descriptor_code]
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :phenomenon, :modifier, :descriptor, :recent
|
75
|
+
|
76
|
+
def initialize(raw, phenomenon:, modifier: nil, descriptor: nil, recent: false)
|
77
|
+
@raw = raw
|
78
|
+
@phenomenon, @modifier, @descriptor = phenomenon, modifier, descriptor
|
79
|
+
@recent = recent
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_s
|
83
|
+
key = [modifier, descriptor, phenomenon].compact.join(' ')
|
84
|
+
I18n.t("metar.present_weather.%s" % key)
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class Metar::Data::Wind < Metar::Data::Base
|
2
|
+
def self.parse(raw)
|
3
|
+
case
|
4
|
+
when raw =~ /^(\d{3})(\d{2}(|MPS|KMH|KT))$/
|
5
|
+
return nil if $1.to_i > 360
|
6
|
+
new(
|
7
|
+
raw,
|
8
|
+
direction: Metar::Data::Direction.new($1),
|
9
|
+
speed: Metar::Data::Speed.parse($2)
|
10
|
+
)
|
11
|
+
when raw =~ /^(\d{3})(\d{2})G(\d{2,3}(|MPS|KMH|KT))$/
|
12
|
+
return nil if $1.to_i > 360
|
13
|
+
new(
|
14
|
+
raw,
|
15
|
+
direction: Metar::Data::Direction.new($1),
|
16
|
+
speed: Metar::Data::Speed.parse($2 + $4),
|
17
|
+
gusts: Metar::Data::Speed.parse($3)
|
18
|
+
)
|
19
|
+
when raw =~ /^VRB(\d{2})G(\d{2,3})(|MPS|KMH|KT)$/
|
20
|
+
speed = $1 + $3
|
21
|
+
gusts = $2 + $3
|
22
|
+
new(
|
23
|
+
raw,
|
24
|
+
direction: :variable_direction,
|
25
|
+
speed: Metar::Data::Speed.parse(speed),
|
26
|
+
gusts: Metar::Data::Speed.parse(gusts)
|
27
|
+
)
|
28
|
+
when raw =~ /^VRB(\d{2}(|MPS|KMH|KT))$/
|
29
|
+
new(raw, direction: :variable_direction, speed: Metar::Data::Speed.parse($1))
|
30
|
+
when raw =~ /^\/{3}(\d{2}(|MPS|KMH|KT))$/
|
31
|
+
new(raw, direction: :unknown_direction, speed: Metar::Data::Speed.parse($1))
|
32
|
+
when raw =~ %r(^/////(|MPS|KMH|KT)$)
|
33
|
+
new(raw, direction: :unknown_direction, speed: :unknown_speed)
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :direction, :speed, :gusts
|
40
|
+
|
41
|
+
def initialize(raw, direction:, speed:, gusts: nil)
|
42
|
+
@raw = raw
|
43
|
+
@direction, @speed, @gusts = direction, speed, gusts
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s(options = {})
|
47
|
+
options = {
|
48
|
+
direction_units: :compass,
|
49
|
+
speed_units: :kilometers_per_hour,
|
50
|
+
}.merge(options)
|
51
|
+
speed =
|
52
|
+
case @speed
|
53
|
+
when :unknown_speed
|
54
|
+
I18n.t('metar.wind.unknown_speed')
|
55
|
+
else
|
56
|
+
@speed.to_s(
|
57
|
+
abbreviated: true,
|
58
|
+
precision: 0,
|
59
|
+
units: options[:speed_units]
|
60
|
+
)
|
61
|
+
end
|
62
|
+
direction =
|
63
|
+
case @direction
|
64
|
+
when :variable_direction
|
65
|
+
I18n.t('metar.wind.variable_direction')
|
66
|
+
when :unknown_direction
|
67
|
+
I18n.t('metar.wind.unknown_direction')
|
68
|
+
else
|
69
|
+
@direction.to_s(units: options[:direction_units])
|
70
|
+
end
|
71
|
+
s = "#{speed} #{direction}"
|
72
|
+
if not @gusts.nil?
|
73
|
+
g = @gusts.to_s(
|
74
|
+
abbreviated: true,
|
75
|
+
precision: 0,
|
76
|
+
units: options[:speed_units]
|
77
|
+
)
|
78
|
+
s += " #{I18n.t('metar.wind.gusts')} #{g}"
|
79
|
+
end
|
80
|
+
s
|
81
|
+
end
|
82
|
+
end
|