metar-parser 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2e0388461861adfdb50306cdb0b8044056ba41f
4
- data.tar.gz: 160ed08277376b4f977b1fc67a0bd97d6969ac76
3
+ metadata.gz: 456cd34e625a1ba09f41ae95253611d7fcacdf20
4
+ data.tar.gz: 45063d94795f39b8bd092258e1ad72eeb207a3c3
5
5
  SHA512:
6
- metadata.gz: df0e0d548d8365d4b637e6fc75287891f640f8df24534a4849fd4d7e805bd389460096eccfd5040a0cf16dc7df74b2936cd996b2ba41e7fd13fdbf3d73e00af7
7
- data.tar.gz: aed5bba18e4875247db0f99762bf9babaf9ff3cc79ada5483ca4c601db6d15fb8360a2a43a5b7af99279ae914881b52a86559e9682a7d138dee282b8cd8cd77d
6
+ metadata.gz: 2a052fccc41b27c6cc87380892c2ac563aaa53b763669c3347d1fdf4daa9c4b3719937880ec5ee820e829cb138262c3a8aa1a37479e0b100159723fcee52c22e
7
+ data.tar.gz: 30afb02c2e7a5b8ecd30fa4e37b03300dffb3600f1224b4d50aa2d5f8f4c63c453ee2530342ca48bf2e04582b65692ab68819607caaeb2d6e2010bae86a6a00b
@@ -17,25 +17,38 @@ class Metar::Data::Lightning < Metar::Data::Base
17
17
  end
18
18
 
19
19
  loop do
20
+ break if chunks[0].nil?
21
+
20
22
  if is_compass?(chunks[0])
21
23
  direction = chunks.shift
22
24
  raw += " " + direction
23
25
  directions << direction
24
- elsif chunks[0] == 'ALQDS'
26
+ next
27
+ end
28
+
29
+ if chunks[0] == 'ALQDS'
25
30
  directions += ['N', 'E', 'S', 'W']
26
31
  raw += " " + chunks.shift
27
- elsif chunks[0] =~ /^([NESW]{1,2})-([NESW]{1,2})$/
28
- if is_compass?($1) and is_compass?($2)
29
- directions += [$1, $2]
32
+ next
33
+ end
34
+
35
+ m = chunks[0].match(/^([NESW]{1,2})-([NESW]{1,2})$/)
36
+ if m
37
+ if is_compass?(m[1]) && is_compass?(m[1])
38
+ directions += [m[1], m[2]]
30
39
  raw += " " + chunks.shift
31
40
  else
32
41
  break
33
42
  end
34
- elsif chunks[0] == 'AND'
43
+ next
44
+ end
45
+
46
+ if chunks[0] == 'AND'
35
47
  raw += " " + chunks.shift
36
- else
37
- break
48
+ next
38
49
  end
50
+
51
+ break
39
52
  end
40
53
 
41
54
  new(
@@ -1,13 +1,20 @@
1
1
  class Metar::Data::Pressure < Metar::Data::Base
2
2
  def self.parse(raw)
3
- case
4
- when raw =~ /^Q(\d{4})$/
5
- new(raw, pressure: M9t::Pressure.hectopascals($1.to_f))
6
- when raw =~ /^A(\d{4})$/
7
- new(raw, pressure: M9t::Pressure.inches_of_mercury($1.to_f / 100.0))
8
- else
9
- nil
3
+ return nil if raw.nil?
4
+
5
+ m1 = raw.match(/^Q(\d{4})$/)
6
+ if m1
7
+ pressure = M9t::Pressure.hectopascals(m1[1].to_f)
8
+ return new(raw, pressure: pressure)
9
+ end
10
+
11
+ m2 = raw.match(/^A(\d{4})$/)
12
+ if m2
13
+ pressure = M9t::Pressure.inches_of_mercury(m2[1].to_f / 100.0)
14
+ return new(raw, pressure: pressure)
10
15
  end
16
+
17
+ nil
11
18
  end
12
19
 
13
20
  attr_reader :pressure
@@ -23,46 +23,84 @@ class Metar::Data::Remark
23
23
  COLOR_CODE = ['RED', 'AMB', 'YLO', 'GRN', 'WHT', 'BLU']
24
24
 
25
25
  def self.parse(raw)
26
- case raw
27
- when /^([12])([01])(\d{3})$/
28
- extreme = {'1' => :maximum, '2' => :minimum}[$1]
29
- value = sign($2) * tenths($3)
30
- Metar::Data::TemperatureExtreme.new(raw, extreme, value)
31
- when /^4([01])(\d{3})([01])(\d{3})$/
32
- [
33
- Metar::Data::TemperatureExtreme.new(raw, :maximum, sign($1) * tenths($2)),
34
- Metar::Data::TemperatureExtreme.new(raw, :minimum, sign($3) * tenths($4)),
26
+ if !raw
27
+ return nil
28
+ end
29
+
30
+ m1 = raw.match(/^([12])([01])(\d{3})$/)
31
+ if m1
32
+ extreme = {'1' => :maximum, '2' => :minimum}[m1[1]]
33
+ value = sign(m1[2]) * tenths(m1[3])
34
+ return Metar::Data::TemperatureExtreme.new(raw, extreme, value)
35
+ end
36
+
37
+ m2 = raw.match(/^4([01])(\d{3})([01])(\d{3})$/)
38
+ if m2
39
+ return [
40
+ Metar::Data::TemperatureExtreme.new(raw, :maximum, sign(m2[1]) * tenths(m2[2])),
41
+ Metar::Data::TemperatureExtreme.new(raw, :minimum, sign(m2[3]) * tenths(m2[4])),
35
42
  ]
36
- when /^5([0-8])(\d{3})$/
37
- character = PRESSURE_CHANGE_CHARACTER[$1.to_i]
38
- Metar::Data::PressureTendency.new(raw, character, tenths($2))
39
- when /^6(\d{4})$/
40
- Metar::Data::Precipitation.new(raw, 3, Metar::Data::Distance.new(inches_to_meters($1))) # actually 3 or 6 depending on reporting time
41
- when /^7(\d{4})$/
42
- Metar::Data::Precipitation.new(raw, 24, Metar::Data::Distance.new(inches_to_meters($1)))
43
- when /^A[0O]([12])$/
44
- type = [:with_precipitation_discriminator, :without_precipitation_discriminator][$1.to_i - 1]
45
- Metar::Data::AutomatedStationType.new(raw, type)
46
- when /^P(\d{4})$/
47
- Metar::Data::Precipitation.new(raw, 1, Metar::Data::Distance.new(inches_to_meters($1)))
48
- when /^T([01])(\d{3})([01])(\d{3})$/
49
- temperature = Metar::Data::Temperature.new(sign($1) * tenths($2))
50
- dew_point = Metar::Data::Temperature.new(sign($3) * tenths($4))
51
- Metar::Data::HourlyTemperatureAndDewPoint.new(raw, temperature, dew_point)
52
- when /^SLP(\d{3})$/
53
- Metar::Data::SeaLevelPressure.new(raw, M9t::Pressure.hectopascals(tenths($1)))
54
- when /^(#{INDICATOR_TYPE.keys.join('|')})NO$/
55
- type = INDICATOR_TYPE[$1]
56
- Metar::Data::SensorStatusIndicator.new(raw, :type, :not_available)
57
- when /^(#{COLOR_CODE.join('|')})$/
58
- Metar::Data::ColorCode.new(raw, $1)
59
- when 'SKC'
60
- Metar::Data::SkyCondition.new(raw)
61
- when '$'
43
+ end
44
+
45
+ m3 = raw.match(/^5([0-8])(\d{3})$/)
46
+ if m3
47
+ character = PRESSURE_CHANGE_CHARACTER[m3[1].to_i]
48
+ return Metar::Data::PressureTendency.new(raw, character, tenths(m3[2]))
49
+ end
50
+
51
+ m4 = raw.match(/^6(\d{4})$/)
52
+ if m4
53
+ return Metar::Data::Precipitation.new(raw, 3, Metar::Data::Distance.new(inches_to_meters(m4[1]))) # actually 3 or 6 depending on reporting time
54
+ end
55
+
56
+ m5 = raw.match(/^7(\d{4})$/)
57
+ if m5
58
+ return Metar::Data::Precipitation.new(raw, 24, Metar::Data::Distance.new(inches_to_meters(m5[1])))
59
+ end
60
+
61
+ m6 = raw.match(/^A[0O]([12])$/)
62
+ if m6
63
+ type = [:with_precipitation_discriminator, :without_precipitation_discriminator][m6[1].to_i - 1]
64
+ return Metar::Data::AutomatedStationType.new(raw, type)
65
+ end
66
+
67
+ m7 = raw.match(/^P(\d{4})$/)
68
+ if m7
69
+ return Metar::Data::Precipitation.new(raw, 1, Metar::Data::Distance.new(inches_to_meters(m7[1])))
70
+ end
71
+
72
+ m8 = raw.match(/^T([01])(\d{3})([01])(\d{3})$/)
73
+ if m8
74
+ temperature = Metar::Data::Temperature.new(sign(m8[1]) * tenths(m8[2]))
75
+ dew_point = Metar::Data::Temperature.new(sign(m8[3]) * tenths(m8[4]))
76
+ return Metar::Data::HourlyTemperatureAndDewPoint.new(raw, temperature, dew_point)
77
+ end
78
+
79
+ m9 = raw.match(/^SLP(\d{3})$/)
80
+ if m9
81
+ return Metar::Data::SeaLevelPressure.new(raw, M9t::Pressure.hectopascals(tenths(m9[1])))
82
+ end
83
+
84
+ m10 = raw.match(/^(#{INDICATOR_TYPE.keys.join('|')})NO$/)
85
+ if m10
86
+ type = INDICATOR_TYPE[m10[1]]
87
+ return Metar::Data::SensorStatusIndicator.new(raw, type, :not_available)
88
+ end
89
+
90
+ m11 = raw.match(/^(#{COLOR_CODE.join('|')})$/)
91
+ if m11
92
+ return Metar::Data::ColorCode.new(raw, m11[1])
93
+ end
94
+
95
+ if raw == 'SKC'
96
+ return Metar::Data::SkyCondition.new(raw)
97
+ end
98
+
99
+ if raw == '$'
62
100
  Metar::Data::MaintenanceNeeded.new(raw)
63
- else
64
- nil
65
101
  end
102
+
103
+ nil
66
104
  end
67
105
 
68
106
  def self.sign(digit)
@@ -4,29 +4,34 @@ class Metar::Data::RunwayVisibleRange < Metar::Data::Base
4
4
  UNITS = {'' => :meters, 'FT' => :feet}
5
5
 
6
6
  def self.parse(raw)
7
- case
8
- when raw =~ /^R(\d+[RLC]?)\/(P|M|)(\d{4})(FT|)\/?(N|U|D|)$/
9
- designator = $1
10
- comparator = COMPARATOR[$2]
11
- count = $3.to_f
12
- units = UNITS[$4]
13
- tendency = TENDENCY[$5]
7
+ return nil if raw.nil?
8
+
9
+ m1 = raw.match(/^R(\d+[RLC]?)\/(P|M|)(\d{4})(FT|)\/?(N|U|D|)$/)
10
+ if m1
11
+ designator = m1[1]
12
+ comparator = COMPARATOR[m1[2]]
13
+ count = m1[3].to_f
14
+ units = UNITS[m1[4]]
15
+ tendency = TENDENCY[m1[5]]
14
16
  distance = Metar::Data::Distance.send(units, count)
15
17
  visibility = Metar::Data::Visibility.new(
16
18
  nil, distance: distance, comparator: comparator
17
19
  )
18
- new(
20
+ return new(
19
21
  raw,
20
22
  designator: designator, visibility1: visibility, tendency: tendency
21
23
  )
22
- when raw =~ /^R(\d+[RLC]?)\/(P|M|)(\d{4})V(P|M|)(\d{4})(FT|)\/?(N|U|D)?$/
23
- designator = $1
24
- comparator1 = COMPARATOR[$2]
25
- count1 = $3.to_f
26
- comparator2 = COMPARATOR[$4]
27
- count2 = $5.to_f
28
- units = UNITS[$6]
29
- tendency = TENDENCY[$7]
24
+ end
25
+
26
+ m2 = raw.match(/^R(\d+[RLC]?)\/(P|M|)(\d{4})V(P|M|)(\d{4})(FT|)\/?(N|U|D)?$/)
27
+ if m2
28
+ designator = m2[1]
29
+ comparator1 = COMPARATOR[m2[2]]
30
+ count1 = m2[3].to_f
31
+ comparator2 = COMPARATOR[m2[4]]
32
+ count2 = m2[5].to_f
33
+ units = UNITS[m2[6]]
34
+ tendency = TENDENCY[m2[7]]
30
35
  distance1 = Metar::Data::Distance.send(units, count1)
31
36
  distance2 = Metar::Data::Distance.send(units, count2)
32
37
  visibility1 = Metar::Data::Visibility.new(
@@ -35,15 +40,15 @@ class Metar::Data::RunwayVisibleRange < Metar::Data::Base
35
40
  visibility2 = Metar::Data::Visibility.new(
36
41
  nil, distance: distance2, comparator: comparator2
37
42
  )
38
- new(
43
+ return new(
39
44
  raw,
40
45
  designator: designator,
41
46
  visibility1: visibility1, visibility2: visibility2,
42
47
  tendency: tendency, units: units
43
48
  )
44
- else
45
- nil
46
49
  end
50
+
51
+ nil
47
52
  end
48
53
 
49
54
  attr_reader :designator, :visibility1, :visibility2, :tendency
@@ -14,25 +14,34 @@ class Metar::Data::SkyCondition < Metar::Data::Base
14
14
  ]
15
15
 
16
16
  def self.parse(raw)
17
- case
18
- when CLEAR_SKIES.include?(raw)
19
- new(raw)
20
- when raw =~ /^(BKN|FEW|OVC|SCT)(\d+|\/{3})(CB|TCU|\/{3}|)?$/
21
- quantity = QUANTITY[$1]
17
+ if !raw
18
+ return nil
19
+ end
20
+
21
+ if CLEAR_SKIES.include?(raw)
22
+ return new(raw)
23
+ end
24
+
25
+ m1 = raw.match(/^(BKN|FEW|OVC|SCT)(\d+|\/{3})(CB|TCU|\/{3}|)?$/)
26
+ if m1
27
+ quantity = QUANTITY[m1[1]]
22
28
  height =
23
- if $2 == '///'
29
+ if m1[2] == '///'
24
30
  nil
25
31
  else
26
- Metar::Data::Distance.new($2.to_i * 30.48)
32
+ Metar::Data::Distance.new(m1[2].to_i * 30.48)
27
33
  end
28
- type = CONDITION[$3]
29
- new(raw, quantity: quantity, height: height, type: type)
30
- when raw =~ /^(CB|TCU)$/
31
- type = CONDITION[$1]
32
- new(raw, type: type)
33
- else
34
- nil
34
+ type = CONDITION[m1[3]]
35
+ return new(raw, quantity: quantity, height: height, type: type)
36
+ end
37
+
38
+ m2 = raw.match(/^(CB|TCU)$/)
39
+ if m2
40
+ type = CONDITION[m2[1]]
41
+ return new(raw, type: type)
35
42
  end
43
+
44
+ nil
36
45
  end
37
46
 
38
47
  attr_reader :quantity, :height, :type
@@ -11,12 +11,10 @@ class Metar::Data::Speed < M9t::Speed
11
11
  }
12
12
 
13
13
  def self.parse(raw)
14
- case
15
- when raw =~ /^(\d+)(|KT|MPS|KMH)$/
16
- # Call the appropriate factory method for the supplied units
17
- send(METAR_UNITS[$2], $1.to_i)
18
- else
19
- nil
20
- end
14
+ return nil if raw.nil?
15
+ m = raw.match(/^(\d+)(|KT|MPS|KMH)$/)
16
+ return nil if m.nil?
17
+ # Call the appropriate factory method for the supplied units
18
+ return send(METAR_UNITS[m[2]], m[1].to_i)
21
19
  end
22
20
  end
@@ -4,14 +4,12 @@ require "m9t"
4
4
  # Adds a parse method to the M9t base class
5
5
  class Metar::Data::Temperature < M9t::Temperature
6
6
  def self.parse(raw)
7
- if raw =~ /^(M?)(\d+)$/
8
- sign = $1
9
- value = $2.to_i
10
- value *= -1 if sign == 'M'
11
- new(value)
12
- else
13
- nil
14
- end
7
+ m = raw.match(/^(M?)(\d+)$/)
8
+ return nil if !m
9
+ sign = m[1]
10
+ value = m[2].to_i
11
+ value *= -1 if sign == 'M'
12
+ new(value)
15
13
  end
16
14
 
17
15
  def to_s(options = {})
@@ -1,10 +1,13 @@
1
1
  class Metar::Data::TemperatureAndDewPoint < Metar::Data::Base
2
2
  def self.parse(raw)
3
- if raw =~ /^(M?\d+|XX|\/\/)\/(M?\d+|XX|\/\/)?$/
4
- temperature = Metar::Data::Temperature.parse($1)
5
- dew_point = Metar::Data::Temperature.parse($2)
6
- new(raw, temperature: temperature, dew_point: dew_point)
7
- end
3
+ return nil if !raw
4
+
5
+ m = raw.match(/^(M?\d+|XX|\/\/)\/(M?\d+|XX|\/\/)?$/)
6
+ return nil if !m
7
+
8
+ temperature = Metar::Data::Temperature.parse(m[1])
9
+ dew_point = Metar::Data::Temperature.parse(m[2])
10
+ new(raw, temperature: temperature, dew_point: dew_point)
8
11
  end
9
12
 
10
13
  attr_reader :temperature
@@ -10,18 +10,17 @@ class Metar::Data::Time < Metar::Data::Base
10
10
  /^(\d{1,2})(\d{2})(\d{2})Z$/
11
11
  end
12
12
 
13
- if raw =~ date_matcher
14
- day, hour, minute = $1.to_i, $2.to_i, $3.to_i
13
+ m1 = raw.match(date_matcher)
14
+ if m1
15
+ day, hour, minute = m1[1].to_i, m1[2].to_i, m1[3].to_i
15
16
  else
16
17
  return nil if strict
17
18
 
18
- if raw =~ /^(\d{1,2})(\d{2})Z$/
19
- # The day is missing, use today's date
20
- day = Time.now.day
21
- hour, minute = $1.to_i, $2.to_i
22
- else
23
- return nil
24
- end
19
+ m2 = raw.match(/^(\d{1,2})(\d{2})Z$/)
20
+ return nil if !m2
21
+ # The day is missing, use today's date
22
+ day = Time.now.day
23
+ hour, minute = m2[1].to_i, m2[2].to_i
25
24
  end
26
25
 
27
26
  new(
@@ -1,14 +1,15 @@
1
1
  class Metar::Data::VariableWind < Metar::Data::Base
2
2
  def self.parse(raw)
3
- if raw =~ /^(\d+)V(\d+)$/
4
- new(
5
- raw,
6
- direction1: Metar::Data::Direction.new($1),
7
- direction2: Metar::Data::Direction.new($2)
8
- )
9
- else
10
- nil
11
- end
3
+ return nil if raw.nil?
4
+
5
+ m = raw.match(/^(\d+)V(\d+)$/)
6
+ return nil if m.nil?
7
+
8
+ return new(
9
+ raw,
10
+ direction1: Metar::Data::Direction.new(m[1]),
11
+ direction2: Metar::Data::Direction.new(m[2])
12
+ )
12
13
  end
13
14
 
14
15
  attr_reader :direction1
@@ -3,14 +3,19 @@ require "m9t"
3
3
 
4
4
  class Metar::Data::VerticalVisibility < Metar::Data::Base
5
5
  def self.parse(raw)
6
- case
7
- when raw =~ /^VV(\d{3})$/
8
- new(raw, distance: Metar::Data::Distance.new($1.to_f * 30.48))
9
- when raw == '///'
10
- new(raw, distance: Metar::Data::Distance.new)
11
- else
12
- nil
6
+ if !raw
7
+ return nil
13
8
  end
9
+ m1 = raw.match(/^VV(\d{3})$/)
10
+ if m1
11
+ return new(raw, distance: Metar::Data::Distance.new(m1[1].to_f * 30.48))
12
+ end
13
+
14
+ if raw == '///'
15
+ return new(raw, distance: Metar::Data::Distance.new)
16
+ end
17
+
18
+ nil
14
19
  end
15
20
 
16
21
  attr_reader :distance
@@ -1,36 +1,59 @@
1
1
  class Metar::Data::Visibility < Metar::Data::Base
2
2
  def self.parse(raw)
3
- case
4
- when raw == '9999'
5
- new(raw, distance: Metar::Data::Distance.new(10000), comparator: :more_than)
6
- when raw =~ /(\d{4})NDV/ # WMO
7
- new(raw, distance: Metar::Data::Distance.new($1.to_f)) # Assuming meters
8
- when (raw =~ /^((1|2)\s|)([1357])\/([248]|16)SM$/) # US
9
- miles = $1.to_f + $3.to_f / $4.to_f
3
+ if !raw
4
+ return nil
5
+ end
6
+
7
+ if raw == '9999'
8
+ return new(raw, distance: Metar::Data::Distance.new(10000), comparator: :more_than)
9
+ end
10
+
11
+ m1 = raw.match(/(\d{4})NDV/) # WMO
12
+ if m1
13
+ return new(raw, distance: Metar::Data::Distance.new(m1[1].to_f)) # Assuming meters
14
+ end
15
+
16
+ m2 = raw.match(/^((1|2)\s|)([1357])\/([248]|16)SM$/) # US
17
+ if m2
18
+ miles = m2[1].to_f + m2[3].to_f / m2[4].to_f
10
19
  distance = Metar::Data::Distance.miles(miles)
11
20
  distance.units = :miles
12
- new(raw, distance: distance)
13
- when raw =~ /^(\d+)SM$/ # US
14
- distance = Metar::Data::Distance.miles($1.to_f)
21
+ return new(raw, distance: distance)
22
+ end
23
+
24
+ m3 = raw.match(/^(\d+)SM$/) # US
25
+ if m3
26
+ distance = Metar::Data::Distance.miles(m3[1].to_f)
15
27
  distance.units = :miles
16
- new(raw, distance: distance)
17
- when raw == 'M1/4SM' # US
28
+ return new(raw, distance: distance)
29
+ end
30
+
31
+ if raw == 'M1/4SM' # US
18
32
  distance = Metar::Data::Distance.miles(0.25)
19
33
  distance.units = :miles
20
- new(raw, distance: distance, comparator: :less_than)
21
- when raw =~ /^(\d+)KM$/
22
- new(raw, distance: Metar::Data::Distance.kilometers($1))
23
- when raw =~ /^(\d+)$/ # We assume meters
24
- new(raw, distance: Metar::Data::Distance.new($1))
25
- when raw =~ /^(\d+)(N|NE|E|SE|S|SW|W|NW)$/
26
- new(
34
+ return new(raw, distance: distance, comparator: :less_than)
35
+ end
36
+
37
+ m4 = raw.match(/^(\d+)KM$/)
38
+ if m4
39
+ return new(raw, distance: Metar::Data::Distance.kilometers(m4[1]))
40
+ end
41
+
42
+ m5 = raw.match(/^(\d+)$/) # We assume meters
43
+ if m5
44
+ return new(raw, distance: Metar::Data::Distance.new(m5[1]))
45
+ end
46
+
47
+ m6 = raw.match(/^(\d+)(N|NE|E|SE|S|SW|W|NW)$/)
48
+ if m6
49
+ return new(
27
50
  raw,
28
- distance: Metar::Data::Distance.meters($1),
29
- direction: M9t::Direction.compass($2)
51
+ distance: Metar::Data::Distance.meters(m6[1]),
52
+ direction: M9t::Direction.compass(m6[2])
30
53
  )
31
- else
32
- nil
33
54
  end
55
+
56
+ nil
34
57
  end
35
58
 
36
59
  attr_reader :distance, :direction, :comparator
@@ -52,7 +52,7 @@ class Metar::Data::WeatherPhenomenon < Metar::Data::Base
52
52
  phenomena = Phenomena.keys.join('|')
53
53
  descriptors = Descriptors.keys.join('|')
54
54
  modifiers = Modifiers.keys.join('|')
55
- modifiers.gsub!(/([\+\-])/) { "\\#$1" }
55
+ modifiers.gsub!(/([\+\-])/) { |m| "\\#{m}" }
56
56
  rxp = Regexp.new("^(RE)?(#{modifiers})?(#{descriptors})?((?:#{phenomena}){1,2})$")
57
57
  m = rxp.match(raw)
58
58
  return nil if m.nil?
@@ -1,39 +1,58 @@
1
1
  class Metar::Data::Wind < Metar::Data::Base
2
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(
3
+ return nil if raw.nil?
4
+
5
+ m1 = raw.match(/^(\d{3})(\d{2}(|MPS|KMH|KT))$/)
6
+ if m1
7
+ return nil if m1[1].to_i > 360
8
+ return new(
7
9
  raw,
8
- direction: Metar::Data::Direction.new($1),
9
- speed: Metar::Data::Speed.parse($2)
10
+ direction: Metar::Data::Direction.new(m1[1]),
11
+ speed: Metar::Data::Speed.parse(m1[2])
10
12
  )
11
- when raw =~ /^(\d{3})(\d{2})G(\d{2,3}(|MPS|KMH|KT))$/
12
- return nil if $1.to_i > 360
13
- new(
13
+ end
14
+
15
+ m2 = raw.match(/^(\d{3})(\d{2})G(\d{2,3}(|MPS|KMH|KT))$/)
16
+ if m2
17
+ return nil if m2[1].to_i > 360
18
+ return new(
14
19
  raw,
15
- direction: Metar::Data::Direction.new($1),
16
- speed: Metar::Data::Speed.parse($2 + $4),
17
- gusts: Metar::Data::Speed.parse($3)
20
+ direction: Metar::Data::Direction.new(m2[1]),
21
+ speed: Metar::Data::Speed.parse(m2[2] + m2[4]),
22
+ gusts: Metar::Data::Speed.parse(m2[3])
18
23
  )
19
- when raw =~ /^VRB(\d{2})G(\d{2,3})(|MPS|KMH|KT)$/
20
- speed = $1 + $3
21
- gusts = $2 + $3
22
- new(
24
+ end
25
+
26
+ m3 = raw.match(/^VRB(\d{2})G(\d{2,3})(|MPS|KMH|KT)$/)
27
+ if m3
28
+ speed = m3[1] + m3[3]
29
+ gusts = m3[2] + m3[3]
30
+ return new(
23
31
  raw,
24
32
  direction: :variable_direction,
25
33
  speed: Metar::Data::Speed.parse(speed),
26
34
  gusts: Metar::Data::Speed.parse(gusts)
27
35
  )
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
36
  end
37
+
38
+ m4 = raw.match(/^VRB(\d{2}(|MPS|KMH|KT))$/)
39
+ if m4
40
+ speed = Metar::Data::Speed.parse(m4[1])
41
+ return new(raw, direction: :variable_direction, speed: speed)
42
+ end
43
+
44
+ m5 = raw.match(/^\/{3}(\d{2}(|MPS|KMH|KT))$/)
45
+ if m5
46
+ speed = Metar::Data::Speed.parse(m5[1])
47
+ return new(raw, direction: :unknown_direction, speed: speed)
48
+ end
49
+
50
+ m6 = raw.match(%r(^/////(|MPS|KMH|KT)$))
51
+ if m6
52
+ return new(raw, direction: :unknown_direction, speed: :unknown_speed)
53
+ end
54
+
55
+ nil
37
56
  end
38
57
 
39
58
  attr_reader :direction, :speed, :gusts
data/lib/metar/station.rb CHANGED
@@ -7,7 +7,7 @@ require 'set'
7
7
 
8
8
  module Metar
9
9
  class Station
10
- NOAA_STATION_LIST_URL = 'http://weather.noaa.gov/data/nsd_cccc.txt'
10
+ NOAA_STATION_LIST_URL = 'http://tgftp.nws.noaa.gov/data/nsd_cccc.txt'
11
11
 
12
12
  class << self
13
13
  @nsd_cccc = nil # Contains the text of the station list
@@ -38,13 +38,15 @@ module Metar
38
38
  end
39
39
 
40
40
  def to_longitude(s)
41
- s =~ /^(\d+)-(\d+)([EW])/ or return nil
42
- ($3 == 'E' ? 1.0 : -1.0) * ($1.to_f + $2.to_f / 60.0)
41
+ m = s.match(/^(\d+)-(\d+)([EW])/)
42
+ return nil if !m
43
+ (m[3] == 'E' ? 1.0 : -1.0) * (m[1].to_f + m[2].to_f / 60.0)
43
44
  end
44
45
 
45
46
  def to_latitude(s)
46
- s =~ /^(\d+)-(\d+)([SN])/ or return nil
47
- ($3 == 'N' ? 1.0 : -1.0) * ($1.to_f + $2.to_f / 60.0)
47
+ m = s.match(/^(\d+)-(\d+)([SN])/)
48
+ return nil if !m
49
+ (m[3] == 'E' ? 1.0 : -1.0) * (m[1].to_f + m[2].to_f / 60.0)
48
50
  end
49
51
  end
50
52
 
data/lib/metar/version.rb CHANGED
@@ -2,7 +2,7 @@ module Metar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 3
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/spec/parser_spec.rb CHANGED
@@ -457,7 +457,6 @@ describe Metar::Parser do
457
457
  sky_conditions
458
458
  ).each do |attr|
459
459
  specify "#{attr} is not set" do
460
- puts "attr: #{attr}"
461
460
  expect(result).to_not include(attr)
462
461
  end
463
462
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metar-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-16 00:00:00.000000000 Z
11
+ date: 2017-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "<"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '11.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "<"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '11.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rdoc
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -237,7 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
237
  version: '0'
238
238
  requirements: []
239
239
  rubyforge_project: nowarning
240
- rubygems_version: 2.5.1
240
+ rubygems_version: 2.5.2
241
241
  signing_key:
242
242
  specification_version: 4
243
243
  summary: A Ruby gem for worldwide weather reports