simple_metar_parser 0.0.0

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.
@@ -0,0 +1,101 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ module SimpleMetarParser
4
+ class Temperature < Base
5
+
6
+ def reset
7
+ @temperature = nil
8
+ @dew = nil
9
+ end
10
+
11
+ # Temperature in C
12
+ attr_reader :temperature
13
+ alias :degrees :temperature
14
+
15
+ # Dew temperature
16
+ attr_reader :dew
17
+
18
+ # Relative humidity
19
+ attr_reader :humidity
20
+
21
+ # Wind chill index
22
+ attr_reader :wind_chill
23
+
24
+ # US Wind chill index
25
+ attr_reader :wind_chill_us
26
+
27
+ def decode_split(s)
28
+ # Temperature in Celsius degrees
29
+ if s =~ /^(M?)(\d{2})\/(M?)(\d{2})$/
30
+ if $1 == "M"
31
+ @temperature = -1.0 * $2.to_f
32
+ else
33
+ @temperature = $2.to_f
34
+ end
35
+
36
+ if $3 == "M"
37
+ @dew = -1.0 * $4.to_f
38
+ else
39
+ @dew = $4.to_f
40
+ end
41
+
42
+ return
43
+ end
44
+
45
+ # shorter version
46
+ if s =~ /^(M?)(\d{2})\/$/
47
+ if $1 == "M"
48
+ @temperature = -1.0 * $2.to_f
49
+ else
50
+ @temperature = $2.to_f
51
+ end
52
+
53
+ return
54
+ end
55
+ end
56
+
57
+ def post_process
58
+ calculate_humidity
59
+ calculate_wind_chill
60
+ end
61
+
62
+ def calculate_humidity
63
+ # Calculate relative humidity
64
+ return if self.temperature.nil? or self.dew.nil?
65
+
66
+ # http://github.com/brandonh/ruby-metar/blob/master/lib/metar.rb
67
+ # http://www.faqs.org/faqs/meteorology/temp-dewpoint/
68
+
69
+ es0 = 6.11 # hPa
70
+ t0 = 273.15 # kelvin
71
+ td = self.dew + t0 # kelvin
72
+ t = self.temperature + t0 # kelvin
73
+ lv = 2500000 # joules/kg
74
+ rv = 461.5 # joules*kelvin/kg
75
+ e = es0 * Math::exp(lv/rv * (1.0/t0 - 1.0/td))
76
+ es = es0 * Math::exp(lv/rv * (1.0/t0 - 1.0/t))
77
+ rh = 100 * e/es
78
+
79
+ @humidity = rh.round
80
+ end
81
+
82
+ def calculate_wind_chill
83
+ return if self.temperature.nil? or self.parent.wind.wind_speed.nil?
84
+ return if self.temperature > 10 or self.parent.wind.wind_speed_kmh < 4.8
85
+
86
+ # http://en.wikipedia.org/wiki/Wind_chill
87
+ v = self.parent.wind.wind_speed
88
+ ta = self.temperature
89
+
90
+ @wind_chill_us = 13.12 +
91
+ 0.6215 * ta -
92
+ 11.37 * v +
93
+ 0.3965 * ta * v
94
+
95
+ @wind_chill = (10.0 * Math.sqrt(v) - v + 10.5)*(33.0 - ta)
96
+ end
97
+
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,47 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ module SimpleMetarParser
4
+ class Visibility < Base
5
+
6
+ # max visibility
7
+ MAX_VISIBILITY = 10_000
8
+
9
+ # If visibility is greater than this it assume it is maximum
10
+ NEARLY_MAX_VISIBILITY = 9_500
11
+
12
+ def reset
13
+ @visibility = nil
14
+ end
15
+
16
+ attr_reader :visibility
17
+
18
+ def decode_split(s)
19
+ # Visibility in meters
20
+
21
+ # Europa
22
+ if s =~ /^(\d{4})$/
23
+ @visibility = $1.to_i
24
+ end
25
+
26
+ # US
27
+ if s =~ /^(\d{1,3})\/?(\d{0,2})SM$/
28
+ if $2 == ""
29
+ @visibility = $1.to_i * 1600.0
30
+ else
31
+ @visibility = $1.to_f * 1600.0 / $2.to_f
32
+ end
33
+ end
34
+
35
+ # constant max value
36
+ if @visibility.to_i >= NEARLY_MAX_VISIBILITY
37
+ @visibility = MAX_VISIBILITY
38
+ end
39
+
40
+ if s =~ /^(CAVOK)$/
41
+ @visibility = MAX_VISIBILITY
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,144 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ module SimpleMetarParser
4
+ class Wind < Base
5
+
6
+ def reset
7
+ @winds = Array.new
8
+ @winds_variable_directions = Array.new
9
+ end
10
+
11
+ KNOTS_TO_METERS_PER_SECOND = 1.85 / 3.6
12
+ KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND = 1.0 / 3.6
13
+
14
+ def decode_split(s)
15
+ decode_wind(s)
16
+ decode_wind_variable(s)
17
+ end
18
+
19
+ def post_process
20
+ recalculate_winds
21
+ end
22
+
23
+ # Wind parameters in meters per second
24
+ def decode_wind(s)
25
+
26
+ if s =~ /(\d{3})(\d{2})G?(\d{2})?(KT|MPS|KMH)/
27
+ # different units
28
+ wind = case $4
29
+ when "KT" then
30
+ $2.to_f * KNOTS_TO_METERS_PER_SECOND
31
+ when "MPS" then
32
+ $2.to_f
33
+ when "KMH" then
34
+ $2.to_f * KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND
35
+ else
36
+ nil
37
+ end
38
+
39
+ wind_max = case $4
40
+ when "KT" then
41
+ $3.to_f * KNOTS_TO_METERS_PER_SECOND
42
+ when "MPS" then
43
+ $3.to_f
44
+ when "KMH" then
45
+ $3.to_f * KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND
46
+ else
47
+ nil
48
+ end
49
+
50
+ # wind_max is not less than normal wind
51
+ if wind_max < wind or wind_max.nil?
52
+ wind_max = wind
53
+ end
54
+
55
+ @winds << {
56
+ :wind => wind,
57
+ :wind_max => wind_max,
58
+ :wind_direction => $1.to_i
59
+ }
60
+ end
61
+
62
+ # variable/unknown direction
63
+ if s =~ /VRB(\d{2})(KT|MPS|KMH)/
64
+ wind = case $2
65
+ when "KT" then
66
+ $1.to_f * KNOTS_TO_METERS_PER_SECOND
67
+ when "MPS" then
68
+ $1.to_f
69
+ when "KMH" then
70
+ $1.to_f * KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND
71
+ else
72
+ nil
73
+ end
74
+
75
+ @winds << {
76
+ :wind => wind
77
+ }
78
+
79
+ end
80
+ end
81
+
82
+ # Variable wind direction
83
+ def decode_wind_variable(s)
84
+ if s =~ /(\d{3})V(\d{3})/
85
+ @winds_variable_directions << {
86
+ :wind_variable_direction_from => $1.to_i,
87
+ :wind_variable_direction_to => $2.to_i,
88
+ :wind_direction => ($1.to_i + $2.to_i) / 2,
89
+ :wind_variable => true
90
+ }
91
+ end
92
+ end
93
+
94
+ # Calculate wind parameters, some metar string has multiple winds recorded
95
+ def recalculate_winds
96
+ @wind = @winds.collect { |w| w[:wind] }.inject(0) { |b, i| b + i } / @winds.size
97
+ if @winds.size == 1
98
+ @wind_direction = @winds.first[:wind_direction]
99
+ else
100
+ @wind_direction = nil
101
+ end
102
+ end
103
+
104
+ # Wind speed in meters per second
105
+ attr_reader :wind
106
+ alias_method :wind_speed, :wind
107
+
108
+ # Direction of wind
109
+ attr_reader :wind_direction
110
+
111
+ # Wind speed in knots
112
+ def wind_speed_knots
113
+ return self.wind if self.wind.nil?
114
+ return self.wind / KNOTS_TO_METERS_PER_SECOND
115
+ end
116
+
117
+ # Wind speed in KM/H
118
+ def wind_speed_kmh
119
+ return self.wind if self.wind.nil?
120
+ return self.wind / KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND
121
+ end
122
+
123
+ # Meters per second
124
+ def mps
125
+ self.wind
126
+ end
127
+
128
+ # Kilometers per hour
129
+ def kmh
130
+ self.wind_speed_kmh
131
+ end
132
+
133
+ # Knots
134
+ def knots
135
+ self.wind_speed_knots
136
+ end
137
+
138
+ # Wind direction
139
+ def direction
140
+ self.wind_direction
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,7 @@
1
+ module SimpleMetarParser
2
+ class Parser
3
+ def self.parse(metar, options = {})
4
+ return Metar.new(metar, options)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+
2
+ # If metar string is valid, processed ok with basic data, and time was correct
3
+ def valid?
4
+ if TYPE_ARCHIVED == @type
5
+ if not @city_metar.nil? and
6
+ not self.temperature.nil? and
7
+ not self.wind.nil? and
8
+ not self.time_from.nil? and
9
+ self.time_from <= Time.now
10
+ return true
11
+ end
12
+
13
+ elsif TYPE_FRESH == @type
14
+ # time should be near now
15
+ if not @city_metar.nil? and
16
+
17
+ self.time_from <= Time.now and
18
+ self.time_from >= (Time.now - 3*24*3600)
19
+ return true
20
+ end
21
+
22
+ end
23
+
24
+ return false
25
+ end
26
+
27
+
28
+
29
+ # Decode runway data. Not yet implemented.
30
+ def decode_runway(s)
31
+ # BIAR 130700Z 17003KT 0350 R01/0900V1500U +SN VV001 M04/M04 Q0996
32
+ # Runway 01, touchdown zone visual range is variable from a minimum of 0900 meters until a maximum of 1500 meters, and increasing
33
+ # http://heras-gilsanz.com/manuel/METAR-Decoder.html
34
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_metar_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aleksander Kwiatkowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &28881540 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.3.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *28881540
25
+ - !ruby/object:Gem::Dependency
26
+ name: bundler
27
+ requirement: &28881060 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *28881060
36
+ - !ruby/object:Gem::Dependency
37
+ name: jeweler
38
+ requirement: &28880580 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.6.4
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *28880580
47
+ - !ruby/object:Gem::Dependency
48
+ name: rcov
49
+ requirement: &18380860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *18380860
58
+ description: Gem for parsing METARs fast and simple.
59
+ email: bobikx@poczta.fm
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files:
63
+ - LICENSE.txt
64
+ - README.rdoc
65
+ files:
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE.txt
69
+ - README.rdoc
70
+ - Rakefile
71
+ - VERSION
72
+ - lib/simple_metar_parser.rb
73
+ - lib/simple_metar_parser/metar.rb
74
+ - lib/simple_metar_parser/metar/base.rb
75
+ - lib/simple_metar_parser/metar/clouds.rb
76
+ - lib/simple_metar_parser/metar/metar_city.rb
77
+ - lib/simple_metar_parser/metar/metar_other.rb
78
+ - lib/simple_metar_parser/metar/metar_specials.rb
79
+ - lib/simple_metar_parser/metar/metar_time.rb
80
+ - lib/simple_metar_parser/metar/pressure.rb
81
+ - lib/simple_metar_parser/metar/temperature.rb
82
+ - lib/simple_metar_parser/metar/visibility.rb
83
+ - lib/simple_metar_parser/metar/wind.rb
84
+ - lib/simple_metar_parser/parser.rb
85
+ - lib/simple_metar_parser/tmp/tmp.rb
86
+ homepage: http://github.com/akwiatkowski/simple_metar_parser
87
+ licenses:
88
+ - LGPLv3
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ segments:
100
+ - 0
101
+ hash: 2798011357648341845
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.15
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Simple METAR parser
114
+ test_files: []