metar-parser 0.9.11 → 0.9.12

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.
data/lib/metar/station.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'rubygems' if RUBY_VERSION < '1.9'
2
1
  require 'open-uri'
3
2
  require 'set'
4
3
 
@@ -14,7 +13,6 @@ module Metar
14
13
  class << self
15
14
 
16
15
  @nsd_cccc = nil # Contains the text of the station list
17
- attr_accessor :nsd_cccc # Allow tests to run from local file
18
16
 
19
17
  def download_local
20
18
  nsd_cccc = Metar::Station.download_stations
@@ -33,7 +31,7 @@ module Metar
33
31
  end
34
32
 
35
33
  def countries
36
- all_structures.reduce( Set.new ) { |a, s| a.add( s[ :country ] ); a }
34
+ all_structures.reduce( Set.new ) { |a, s| a.add( s[ :country ] ) }.to_a.sort
37
35
  end
38
36
 
39
37
  def all
@@ -44,6 +42,10 @@ module Metar
44
42
  end
45
43
  end
46
44
 
45
+ def find_by_cccc(cccc)
46
+ all.find { |station| station.cccc == cccc }
47
+ end
48
+
47
49
  # Does the given CCCC code exist?
48
50
  def exist?(cccc)
49
51
  not find_data_by_cccc(cccc).nil?
@@ -53,10 +55,6 @@ module Metar
53
55
  all.select { | s | s.country == country }
54
56
  end
55
57
 
56
- def find_by_cccc(cccc)
57
- all.find { |station| station.cccc == cccc }
58
- end
59
-
60
58
  def to_longitude(s)
61
59
  s =~ /^(\d+)-(\d+)([EW])/ or return nil
62
60
  ($3 == 'E' ? 1.0 : -1.0) * ($1.to_f + $2.to_f / 60.0)
@@ -68,64 +66,23 @@ module Metar
68
66
  end
69
67
  end
70
68
 
71
- attr_reader :cccc, :loaded
69
+ attr_reader :cccc, :name, :state, :country, :longitude, :latitude, :raw
72
70
  alias :code :cccc
73
- # loaded? indicates whether the data has been collected from the Web
74
- alias :loaded? :loaded
75
71
 
76
72
  # No check is made on the existence of the station
77
- def initialize(cccc, options = {})
78
- raise "Station identifier must not be nil" if cccc.nil?
79
- raise "Station identifier must be a text" if not cccc.respond_to?('to_s')
80
- @cccc = cccc
81
- @name = options[:name]
82
- @state = options[:state]
83
- @country = options[:country]
84
- @longitude = options[:longitude]
85
- @latitude = options[:latitude]
86
- @raw = options[:raw]
87
- @loaded = false
73
+ def initialize( cccc, noaa_data )
74
+ raise "Station identifier must not be nil" if cccc.nil?
75
+ raise "Station identifier must not be empty" if cccc.to_s == ''
76
+ @cccc = cccc
77
+ load! noaa_data
88
78
  end
89
79
 
90
- # Lazy loaded attributes
91
- ## TODO: DRY this up by generating these methods
92
- def name
93
- load! if not @loaded
94
- @name
95
- end
96
-
97
- def state
98
- load! if not @loaded
99
- @state
100
- end
101
-
102
- def country
103
- load! if not @loaded
104
- @country
105
- end
106
-
107
- def latitude
108
- load! if not @loaded
109
- @latitude
110
- end
111
-
112
- def longitude
113
- load! if not @loaded
114
- @longitude
115
- end
116
-
117
- def raw
118
- load! if not @loaded
119
- @raw
120
- end
121
-
122
- def exist?
123
- Station.exist?(@cccc)
80
+ def parser
81
+ raw = Metar::Raw.new( @cccc )
82
+ Metar::Parser.new( raw )
124
83
  end
125
84
 
126
85
  def report
127
- raw = Metar::Raw.new( @cccc )
128
- parser = Metar::Parser.new( raw )
129
86
  Metar::Report.new( parser )
130
87
  end
131
88
 
@@ -172,20 +129,16 @@ module Metar
172
129
 
173
130
  end
174
131
 
175
- # Get data from the NOAA data file (very slow on first call!)
176
- def load!
177
- noaa_data = Station.find_data_by_cccc(@cccc)
178
- raise "Station identifier '#{ @cccc }' not found" if noaa_data.nil?
132
+ def load!( noaa_data )
179
133
  @name = noaa_data[:name]
180
134
  @state = noaa_data[:state]
181
135
  @country = noaa_data[:country]
182
136
  @longitude = Station.to_longitude(noaa_data[:longitude])
183
137
  @latitude = Station.to_latitude(noaa_data[:latitude])
184
138
  @raw = noaa_data[:raw]
185
- @loaded = true
186
- self
187
139
  end
188
140
 
189
141
  end
190
142
 
191
143
  end
144
+
data/lib/metar/version.rb CHANGED
@@ -3,7 +3,7 @@ module Metar
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = 0
5
5
  MINOR = 9
6
- TINY = 11
6
+ TINY = 12
7
7
 
8
8
  STRING = [ MAJOR, MINOR, TINY ].join( '.' )
9
9
  end
data/locales/en.yml CHANGED
@@ -6,6 +6,10 @@ en:
6
6
  comparison:
7
7
  more_than: more than
8
8
  less_than: less than
9
+ tendency:
10
+ no_change: no change
11
+ improving: improving
12
+ worsening: worsening
9
13
  units:
10
14
  pressure:
11
15
  bar:
@@ -34,6 +38,7 @@ en:
34
38
  variable_direction: variable direction
35
39
  unknown_direction: unknown direction
36
40
  unknown_speed: unknown speed
41
+ gusts: gusts
37
42
  variable_wind:
38
43
  title: wind variation
39
44
  visibility:
@@ -147,6 +152,7 @@ en:
147
152
  temperature:
148
153
  title: temperature
149
154
  dew_point:
150
- title: punto di rugiada
155
+ title: dew point
151
156
  remarks:
152
- title: annotazioni
157
+ title: remarks
158
+
data/locales/it.yml CHANGED
@@ -6,6 +6,10 @@ it:
6
6
  comparison:
7
7
  more_than: piú di
8
8
  less_than: meno di
9
+ tendency:
10
+ no_change: invariato
11
+ improving: in miglioramento
12
+ worsening: tendente a peggiorare
9
13
  units:
10
14
  pressure:
11
15
  bar:
@@ -34,6 +38,7 @@ it:
34
38
  variable_direction: direzione variabile
35
39
  unknown_direction: direzione sconosciuta
36
40
  unknown_speed: velocità sconosciuta
41
+ gusts: folate di
37
42
  variable_wind:
38
43
  title: variazione del vento
39
44
  visibility:
@@ -150,3 +155,4 @@ it:
150
155
  title: punto di rugiada
151
156
  remarks:
152
157
  title: annotazioni
158
+
@@ -0,0 +1,5 @@
1
+ require 'rspec'
2
+ require 'rspec/autorun'
3
+
4
+ require File.expand_path( File.dirname(__FILE__) + '/../lib/metar' )
5
+
@@ -0,0 +1,85 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+
3
+ describe Metar::Distance do
4
+
5
+ context '#value' do
6
+
7
+ it 'should treat the parameter as meters' do
8
+ @distance = Metar::Distance.new( 12345.67 )
9
+
10
+ @distance.units. should == :meters
11
+ @distance.value. should == 12345.67
12
+ end
13
+
14
+ end
15
+
16
+ context '#to_s' do
17
+
18
+ it 'should default to meters' do
19
+ @distance = Metar::Distance.new( rand * 1000.0 )
20
+
21
+ @distance.to_s. should =~ %r(^\d+m)
22
+ end
23
+
24
+ it 'should round down to the nearest meter' do
25
+ @distance = Metar::Distance.new( 12.345 )
26
+
27
+ @distance.to_s. should == '12m'
28
+ end
29
+
30
+ it 'should round up to meters' do
31
+ @distance = Metar::Distance.new( 8.750 )
32
+
33
+ @distance.to_s. should == '9m'
34
+ end
35
+
36
+ it 'should allow units overrides' do
37
+ @distance = Metar::Distance.new( 12345.67 )
38
+
39
+ @distance.to_s( :units => :kilometers ).
40
+ should == '12km'
41
+ end
42
+
43
+ it 'should allow precision overrides' do
44
+ @distance = Metar::Distance.new( 12.34567 )
45
+
46
+ @distance.to_s( :precision => 1 ).
47
+ should == '12.3m'
48
+ end
49
+
50
+ it 'should handle nil' do
51
+ @distance = Metar::Distance.new( nil )
52
+
53
+ @distance.to_s. should == 'unknown'
54
+ end
55
+
56
+ context 'translated' do
57
+
58
+ before :each do
59
+ @locale = I18n.locale
60
+ I18n.locale = :it
61
+ end
62
+
63
+ after :each do
64
+ I18n.locale = @locale
65
+ end
66
+
67
+ it 'should allow precision overrides' do
68
+ @distance = Metar::Distance.new( 12.34567 )
69
+
70
+ @distance.to_s( :precision => 1 ).
71
+ should == '12,3m'
72
+ end
73
+
74
+ it 'should handle nil' do
75
+ @distance = Metar::Distance.new( nil )
76
+
77
+ @distance.to_s. should == 'sconosciuto'
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
@@ -0,0 +1,234 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ # encoding: utf-8
3
+
4
+ describe Metar::Parser do
5
+
6
+ context '.for_cccc' do
7
+
8
+ it 'returns a loaded parser' do
9
+ station = stub( 'station' )
10
+ raw = stub( 'raw', :metar => "XXXX 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000",
11
+ :time => '2010/02/06 16:10' )
12
+ Metar::Station.stub!( :new => station )
13
+ Metar::Raw.stub!( :new => raw )
14
+
15
+ parser = Metar::Parser.for_cccc( 'XXXX' )
16
+
17
+ parser. should be_a( Metar::Parser )
18
+ parser.station_code. should == 'XXXX'
19
+ end
20
+
21
+ end
22
+
23
+ context 'attributes' do
24
+
25
+ it '.location missing' do
26
+ expect do
27
+ setup_parser('PAIL', "2010/02/06 16:10\nFUBAR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
28
+ end. to raise_error( Metar::ParseError, /Expecting location/ )
29
+ end
30
+
31
+ it '.time missing' do
32
+ expect do
33
+ setup_parser('PAIL', "2010/02/06 16:10\nPAIL 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
34
+ end. to raise_error( Metar::ParseError, /Expecting datetime/ )
35
+ end
36
+
37
+ it 'date' do
38
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
39
+ parser.date. should == Date.new(2010, 2, 6)
40
+ end
41
+
42
+ context '.observer' do
43
+
44
+ it 'real' do
45
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
46
+ parser.observer. should == :real
47
+ end
48
+
49
+ it 'auto' do
50
+ parser = setup_parser('CYXS', "2010/02/15 10:34\nCYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
51
+
52
+ parser.observer. should == :auto
53
+ end
54
+
55
+ it 'corrected' do
56
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z COR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
57
+ parser.observer. should == :corrected
58
+ end
59
+
60
+ end
61
+
62
+ it 'wind' do
63
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
64
+ parser.wind.direction.value. should be_within( 0.0001 ).of( 240 )
65
+ parser.wind.speed.to_knots. should be_within( 0.0001 ).of( 6 )
66
+ end
67
+
68
+ it 'variable_wind' do
69
+ parser = setup_parser('LIRQ', "2010/02/06 15:20\nLIRQ 061520Z 01007KT 350V050 9999 SCT035 BKN080 08/02 Q1005")
70
+ parser.variable_wind.direction1.value.should be_within( 0.0001 ).of( 350 )
71
+ parser.variable_wind.direction2.value.should be_within( 0.0001 ).of( 50 )
72
+ end
73
+
74
+ context '.visibility' do
75
+ it 'CAVOK' do
76
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT CAVOK M17/M20 A2910 RMK AO2 P0000")
77
+
78
+ parser.visibility.distance.value.
79
+ should be_within( 0.01 ).of( 10000.00 )
80
+ parser.visibility.comparator.
81
+ should == :more_than
82
+ parser.present_weather.size.
83
+ should == 1
84
+ parser.present_weather[ 0 ].phenomenon.
85
+ should == 'No significant weather'
86
+ parser.sky_conditions.size.
87
+ should == 1
88
+ parser.sky_conditions[ 0 ].type.
89
+ should == nil
90
+ end
91
+
92
+ it 'visibility_miles_and_fractions' do
93
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
94
+
95
+ parser.visibility.distance.to_miles.
96
+ should be_within( 0.01 ).of( 1.75 )
97
+ end
98
+
99
+ it '//// with automatic observer' do
100
+ parser = setup_parser('CYXS', "2010/02/15 10:34\nCYXS 151034Z AUTO 09003KT //// FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
101
+
102
+ parser.visibility. should be_nil
103
+ end
104
+ end
105
+
106
+ it 'runway_visible_range' do
107
+ parser = setup_parser('ESSB', "2010/02/15 10:20\nESSB 151020Z 26003KT 2000 R12/1000N R30/1500N VV002 M07/M07 Q1013 1271//55")
108
+ parser.runway_visible_range.length. should == 2
109
+ parser.runway_visible_range[0].designator. should == '12'
110
+ parser.runway_visible_range[0].visibility1.distance.value. should == 1000
111
+ parser.runway_visible_range[0].tendency. should == :no_change
112
+ end
113
+
114
+ it 'runway_visible_range_defaults_to_empty_array' do
115
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
116
+ parser.runway_visible_range.length. should == 0
117
+ end
118
+
119
+ it 'runway_visible_range_variable' do
120
+ parser = setup_parser('KPDX', "2010/02/15 11:08\nKPDX 151108Z 11006KT 1/4SM R10R/1600VP6000FT FG OVC002 05/05 A3022 RMK AO2")
121
+
122
+ parser.runway_visible_range[0].visibility1.distance.to_feet. should == 1600.0
123
+ parser.runway_visible_range[0].visibility2.distance.to_feet. should == 6000.0
124
+ end
125
+
126
+ context '.present_weather' do
127
+
128
+ it 'normal' do
129
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
130
+
131
+ parser.present_weather.size.
132
+ should == 1
133
+ parser.present_weather[0].modifier.
134
+ should == 'light'
135
+ parser.present_weather[0].phenomenon.
136
+ should == 'snow'
137
+ end
138
+
139
+ it 'auto + //' do
140
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z AUTO 24006KT 1 3/4SM // BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
141
+
142
+ parser.present_weather.size.
143
+ should == 1
144
+ parser.present_weather[0].phenomenon.
145
+ should == 'not observed'
146
+ end
147
+
148
+ end
149
+
150
+ it 'present_weather_defaults_to_empty_array' do
151
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
152
+ parser.present_weather.length. should == 0
153
+ end
154
+
155
+ context '.sky_conditions' do
156
+
157
+ it 'normal' do
158
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
159
+
160
+ parser.sky_conditions.size.
161
+ should == 2
162
+ parser.sky_conditions[0].quantity.
163
+ should == 'broken'
164
+ parser.sky_conditions[0].height.value.
165
+ should == 480
166
+ parser.sky_conditions[1].quantity.
167
+ should == 'overcast'
168
+ parser.sky_conditions[1].height.value.
169
+ should == 900
170
+ end
171
+
172
+ it 'auto + ///' do
173
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z AUTO 24006KT 1 3/4SM /// M17/M20 A2910 RMK AO2 P0000")
174
+
175
+ parser.sky_conditions.size.
176
+ should == 0
177
+ end
178
+
179
+ end
180
+
181
+ it 'sky_conditions_defaults_to_empty_array' do
182
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN M17/M20 A2910 RMK AO2 P0000")
183
+ parser.sky_conditions.length. should == 0
184
+ end
185
+
186
+ it 'vertical_visibility' do
187
+ parser = setup_parser('CYXS', "2010/02/15 10:34\nCYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
188
+ parser.vertical_visibility.value. should == 30
189
+ end
190
+
191
+ it 'temperature_obligatory' do
192
+ expect do
193
+ setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 A2910 RMK AO2 P0000")
194
+ end. to raise_error( Metar::ParseError )
195
+ end
196
+
197
+ it 'temperature' do
198
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
199
+ parser.temperature.value. should == -17
200
+ end
201
+
202
+ it 'dew_point' do
203
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
204
+ parser.dew_point.value. should == -20
205
+ end
206
+
207
+ it 'sea_level_pressure' do
208
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
209
+ parser.sea_level_pressure.to_inches_of_mercury. should == 29.10
210
+ end
211
+
212
+ it 'remarks' do
213
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
214
+ parser.remarks. should be_a Array
215
+ parser.remarks.length. should == 2
216
+ parser.remarks[0]. should == 'AO2'
217
+ parser.remarks[1]. should == 'P0000'
218
+ end
219
+
220
+ it 'remarks_defaults_to_empty_array' do
221
+ parser = setup_parser('PAIL', "2010/02/06 16:10\nPAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910")
222
+ parser.remarks. should be_a Array
223
+ parser.remarks.length. should == 0
224
+ end
225
+
226
+ def setup_parser( cccc, metar )
227
+ raw = Metar::Raw.new( cccc, metar )
228
+ Metar::Parser.new( raw )
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+