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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metar/data/base.rb +15 -0
  3. data/lib/metar/data/density_altitude.rb +15 -0
  4. data/lib/metar/data/direction.rb +9 -0
  5. data/lib/metar/data/distance.rb +27 -0
  6. data/lib/metar/data/lightning.rb +61 -0
  7. data/lib/metar/data/observer.rb +24 -0
  8. data/lib/metar/data/pressure.rb +23 -0
  9. data/lib/metar/data/remark.rb +98 -0
  10. data/lib/metar/data/runway_visible_range.rb +85 -0
  11. data/lib/metar/data/sky_condition.rb +61 -0
  12. data/lib/metar/data/speed.rb +22 -0
  13. data/lib/metar/data/station_code.rb +7 -0
  14. data/lib/metar/data/temperature.rb +21 -0
  15. data/lib/metar/data/temperature_and_dew_point.rb +18 -0
  16. data/lib/metar/data/time.rb +54 -0
  17. data/lib/metar/data/variable_wind.rb +25 -0
  18. data/lib/metar/data/vertical_visibility.rb +26 -0
  19. data/lib/metar/data/visibility.rb +71 -0
  20. data/lib/metar/data/visibility_remark.rb +8 -0
  21. data/lib/metar/data/weather_phenomenon.rb +86 -0
  22. data/lib/metar/data/wind.rb +82 -0
  23. data/lib/metar/data.rb +22 -636
  24. data/lib/metar/i18n.rb +6 -0
  25. data/lib/metar/parser.rb +165 -120
  26. data/lib/metar/report.rb +1 -1
  27. data/lib/metar/version.rb +2 -2
  28. data/lib/metar.rb +7 -6
  29. data/locales/de.yml +1 -0
  30. data/locales/en.yml +1 -0
  31. data/locales/it.yml +2 -1
  32. data/locales/pt-BR.yml +1 -0
  33. data/spec/data/density_altitude_spec.rb +12 -0
  34. data/spec/{distance_spec.rb → data/distance_spec.rb} +1 -1
  35. data/spec/data/lightning_spec.rb +49 -0
  36. data/spec/data/pressure_spec.rb +22 -0
  37. data/spec/data/remark_spec.rb +99 -0
  38. data/spec/data/runway_visible_range_spec.rb +92 -0
  39. data/spec/{sky_condition_spec.rb → data/sky_condition_spec.rb} +10 -6
  40. data/spec/data/speed_spec.rb +45 -0
  41. data/spec/data/temperature_spec.rb +36 -0
  42. data/spec/{variable_wind_spec.rb → data/variable_wind_spec.rb} +6 -6
  43. data/spec/{vertical_visibility_spec.rb → data/vertical_visibility_spec.rb} +2 -2
  44. data/spec/{data_spec.rb → data/visibility_remark_spec.rb} +1 -11
  45. data/spec/{visibility_spec.rb → data/visibility_spec.rb} +9 -7
  46. data/spec/{weather_phenomenon_spec.rb → data/weather_phenomenon_spec.rb} +7 -3
  47. data/spec/{wind_spec.rb → data/wind_spec.rb} +10 -7
  48. data/spec/parser_spec.rb +107 -13
  49. data/spec/report_spec.rb +12 -1
  50. data/spec/spec_helper.rb +1 -1
  51. data/spec/station_spec.rb +2 -1
  52. metadata +56 -31
  53. data/spec/pressure_spec.rb +0 -22
  54. data/spec/remark_spec.rb +0 -147
  55. data/spec/runway_visible_range_spec.rb +0 -81
  56. data/spec/speed_spec.rb +0 -45
  57. 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