earth 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/LICENSE-PREAMBLE +1 -1
- data/Rakefile +3 -0
- data/earth.gemspec +1 -1
- data/lib/earth.rb +7 -7
- data/lib/earth/air/aircraft.rb +15 -0
- data/lib/earth/air/aircraft/data_miner.rb +65 -77
- data/lib/earth/air/aircraft_class.rb +1 -1
- data/lib/earth/air/aircraft_fuel_use_equation.rb +1 -1
- data/lib/earth/air/airline.rb +1 -1
- data/lib/earth/air/airport.rb +1 -1
- data/lib/earth/air/bts_aircraft.rb +1 -1
- data/lib/earth/air/flight_distance_class.rb +1 -1
- data/lib/earth/air/flight_seat_class.rb +1 -1
- data/lib/earth/air/flight_segment.rb +1 -1
- data/lib/earth/air/flight_segment/data_miner.rb +24 -46
- data/lib/earth/automobile/automobile_fuel.rb +1 -1
- data/lib/earth/automobile/automobile_make.rb +1 -1
- data/lib/earth/automobile/automobile_make_fleet_year.rb +1 -1
- data/lib/earth/automobile/automobile_make_model.rb +1 -1
- data/lib/earth/automobile/automobile_make_model_year.rb +1 -1
- data/lib/earth/automobile/automobile_make_model_year_variant.rb +1 -1
- data/lib/earth/automobile/automobile_make_year.rb +1 -1
- data/lib/earth/automobile/automobile_size_class.rb +1 -1
- data/lib/earth/automobile/automobile_size_class_year.rb +1 -1
- data/lib/earth/automobile/automobile_type_fuel_age.rb +1 -1
- data/lib/earth/automobile/automobile_type_fuel_control.rb +1 -1
- data/lib/earth/automobile/automobile_type_fuel_year.rb +1 -1
- data/lib/earth/automobile/automobile_type_fuel_year_age.rb +1 -1
- data/lib/earth/automobile/automobile_type_fuel_year_control.rb +1 -1
- data/lib/earth/automobile/automobile_type_year.rb +1 -1
- data/lib/earth/bus/bus_class.rb +1 -1
- data/lib/earth/bus/bus_fuel.rb +1 -1
- data/lib/earth/bus/bus_fuel_control.rb +1 -1
- data/lib/earth/bus/bus_fuel_year_control.rb +1 -1
- data/lib/earth/computation/computation_carrier.rb +1 -1
- data/lib/earth/computation/computation_carrier_instance_class.rb +1 -1
- data/lib/earth/computation/computation_carrier_region.rb +1 -1
- data/lib/earth/conversions_ext.rb +1 -0
- data/lib/earth/diet/diet_class.rb +1 -1
- data/lib/earth/diet/food_group.rb +1 -1
- data/lib/earth/fuel/fuel.rb +1 -1
- data/lib/earth/fuel/fuel_price.rb +1 -1
- data/lib/earth/fuel/fuel_type.rb +1 -1
- data/lib/earth/fuel/fuel_year.rb +1 -1
- data/lib/earth/fuel/greenhouse_gas.rb +1 -1
- data/lib/earth/hospitality/lodging_class.rb +1 -1
- data/lib/earth/industry/industry.rb +1 -1
- data/lib/earth/industry/industry_product.rb +1 -1
- data/lib/earth/industry/industry_product_line.rb +1 -1
- data/lib/earth/industry/industry_sector.rb +1 -1
- data/lib/earth/industry/merchant.rb +1 -1
- data/lib/earth/industry/merchant_category.rb +1 -1
- data/lib/earth/industry/merchant_category_industry.rb +1 -1
- data/lib/earth/industry/product_line.rb +1 -1
- data/lib/earth/industry/product_line_industry_product.rb +1 -1
- data/lib/earth/industry/sector.rb +1 -1
- data/lib/earth/locality/census_division.rb +1 -1
- data/lib/earth/locality/census_region.rb +1 -1
- data/lib/earth/locality/climate_division.rb +1 -1
- data/lib/earth/locality/country.rb +1 -1
- data/lib/earth/locality/egrid_region.rb +1 -1
- data/lib/earth/locality/egrid_region/data_miner.rb +10 -0
- data/lib/earth/locality/egrid_subregion.rb +1 -1
- data/lib/earth/locality/petroleum_administration_for_defense_district.rb +1 -1
- data/lib/earth/locality/state.rb +1 -1
- data/lib/earth/locality/urbanity.rb +1 -1
- data/lib/earth/locality/zip_code.rb +1 -1
- data/lib/earth/pet/breed.rb +1 -1
- data/lib/earth/pet/breed_gender.rb +1 -1
- data/lib/earth/pet/gender.rb +1 -1
- data/lib/earth/pet/species.rb +1 -1
- data/lib/earth/rail/rail_class.rb +1 -1
- data/lib/earth/residence/air_conditioner_use.rb +1 -1
- data/lib/earth/residence/clothes_machine_use.rb +1 -1
- data/lib/earth/residence/dishwasher_use.rb +1 -1
- data/lib/earth/residence/residence_appliance.rb +1 -1
- data/lib/earth/residence/residence_class.rb +1 -1
- data/lib/earth/residence/residence_fuel_price.rb +1 -1
- data/lib/earth/residence/residence_fuel_type.rb +1 -1
- data/lib/earth/residence/residential_energy_consumption_survey_response.rb +1 -1
- data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +9 -9
- data/lib/earth/shipping/carrier.rb +1 -1
- data/lib/earth/shipping/carrier_mode.rb +1 -1
- data/lib/earth/shipping/shipment_mode.rb +1 -1
- data/lib/earth/version.rb +1 -1
- data/spec/earth/air/aircraft_spec.rb +1 -1
- metadata +42 -44
data/Gemfile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
gem 'data_miner', :path => ENV['LOCAL_DATA_MINER'] if ENV['LOCAL_DATA_MINER']
|
2
|
-
gem '
|
2
|
+
gem 'force_schema', :path => ENV['LOCAL_FORCE_SCHEMA'] if ENV['LOCAL_FORCE_SCHEMA']
|
3
3
|
|
4
4
|
source :rubygems
|
5
5
|
|
data/LICENSE-PREAMBLE
CHANGED
@@ -9,7 +9,7 @@ IDENTITY OF THE SOFTWARE MODULE COVERED BY LICENSE:
|
|
9
9
|
|
10
10
|
This license covers the Brighter Planet reference data import module,
|
11
11
|
referred to as 'earth,' officially distributed from
|
12
|
-
|
12
|
+
https://github.com/brighterplanet/earth.
|
13
13
|
|
14
14
|
SCOPE OF THE SOFTWARE MODULE COVERED BY LICENSE:
|
15
15
|
|
data/Rakefile
CHANGED
data/earth.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
s.add_runtime_dependency 'geokit-rails'
|
37
37
|
s.add_runtime_dependency 'loose_tight_dictionary', '>=0.2.3'
|
38
38
|
s.add_runtime_dependency 'weighted_average'
|
39
|
-
s.add_runtime_dependency '
|
39
|
+
s.add_runtime_dependency 'force_schema', '>=0.0.2'
|
40
40
|
s.add_development_dependency 'bundler'
|
41
41
|
s.add_development_dependency 'bueller'
|
42
42
|
s.add_development_dependency 'cucumber'
|
data/lib/earth.rb
CHANGED
@@ -7,7 +7,7 @@ require 'falls_back_on'
|
|
7
7
|
require 'weighted_average'
|
8
8
|
require 'fixed_width'
|
9
9
|
require 'errata'
|
10
|
-
require '
|
10
|
+
require 'force_schema'
|
11
11
|
require 'loose_tight_dictionary'
|
12
12
|
require 'loose_tight_dictionary/cached_result'
|
13
13
|
|
@@ -119,13 +119,13 @@ module Earth
|
|
119
119
|
resource_model.data_miner_config.steps.push pull_dependencies_step
|
120
120
|
end
|
121
121
|
|
122
|
-
def
|
122
|
+
def _prepend_force_schema_step_to_data_miner(resource)
|
123
123
|
resource_model = resource.constantize
|
124
|
-
return if resource_model.data_miner_config.steps.any? { |step| step.description == :
|
124
|
+
return if resource_model.data_miner_config.steps.any? { |step| step.description == :force_schema! }
|
125
125
|
|
126
|
-
|
126
|
+
force_schema_step = DataMiner::Process.new resource_model.data_miner_config, :force_schema!
|
127
127
|
|
128
|
-
resource_model.data_miner_config.steps.unshift
|
128
|
+
resource_model.data_miner_config.steps.unshift force_schema_step
|
129
129
|
end
|
130
130
|
|
131
131
|
TAPS_STEP = 'Tap the Brighter Planet data server'
|
@@ -144,7 +144,7 @@ module Earth
|
|
144
144
|
next unless ::Object.const_defined?(resource)
|
145
145
|
_append_pull_dependencies_step_to_data_miner resource
|
146
146
|
if options[:apply_schemas] or options[:load_data_miner]
|
147
|
-
|
147
|
+
_prepend_force_schema_step_to_data_miner resource
|
148
148
|
else
|
149
149
|
_prepend_taps_step_to_data_miner resource
|
150
150
|
end
|
@@ -154,7 +154,7 @@ module Earth
|
|
154
154
|
def _load_schemas(selected_resources, options)
|
155
155
|
return unless options[:apply_schemas]
|
156
156
|
selected_resources.each do |resource|
|
157
|
-
resource.constantize.
|
157
|
+
resource.constantize.force_schema!
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
data/lib/earth/air/aircraft.rb
CHANGED
@@ -17,6 +17,21 @@ class Aircraft < ActiveRecord::Base
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
force_schema do
|
21
|
+
string 'icao_code'
|
22
|
+
string 'manufacturer_name'
|
23
|
+
string 'model_name'
|
24
|
+
string 'description'
|
25
|
+
string 'aircraft_type'
|
26
|
+
string 'engine_type'
|
27
|
+
integer 'engines'
|
28
|
+
string 'weight_class'
|
29
|
+
string 'class_code'
|
30
|
+
string 'fuel_use_code'
|
31
|
+
float 'seats'
|
32
|
+
float 'passengers'
|
33
|
+
end
|
34
|
+
|
20
35
|
# Enable aircraft.flight_segments
|
21
36
|
cache_loose_tight_dictionary_matches_with :flight_segments, :primary_key => :description, :foreign_key => :aircraft_description
|
22
37
|
end
|
@@ -20,22 +20,69 @@ Aircraft.class_eval do
|
|
20
20
|
@manufacturer_whitelist ||= RemoteTable.new(:url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdFRFalpOdlg1cnF6amlSM1dDc1lya2c&output=csv').map { |record| record['Manufacturer'].to_regexp }
|
21
21
|
@manufacturer_whitelist.any? { |manufacturer_regexp| manufacturer_regexp.match candidate }
|
22
22
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
string 'fuel_use_code'
|
35
|
-
float 'seats'
|
36
|
-
float 'passengers'
|
23
|
+
|
24
|
+
# FIXME TODO do we want to restrict this to certain years?
|
25
|
+
# Derive some average characteristics from flight segments
|
26
|
+
def self.update_averages!
|
27
|
+
FlightSegment.run_data_miner!
|
28
|
+
manually_cache_flight_segments!
|
29
|
+
find_each do |aircraft|
|
30
|
+
aircraft.seats = aircraft.flight_segments.weighted_average :seats_per_flight, :weighted_by => :passengers
|
31
|
+
aircraft.passengers = aircraft.flight_segments.sum :passengers
|
32
|
+
aircraft.save
|
33
|
+
end
|
37
34
|
end
|
38
35
|
|
36
|
+
# Cache fuzzy matches between FlightSegment aircraft_description and Aircraft description
|
37
|
+
def self.manually_cache_flight_segments!
|
38
|
+
FlightSegment.run_data_miner!
|
39
|
+
LooseTightDictionary::CachedResult.setup
|
40
|
+
FlightSegment.find_by_sql("SELECT * FROM flight_segments GROUP BY aircraft_description HAVING aircraft_description IS NOT NULL").each do |flight_segment|
|
41
|
+
original_description = flight_segment.aircraft_description
|
42
|
+
|
43
|
+
# If the flight segment's aircraft_description contains '/' then it describes multiple aircraft.
|
44
|
+
# We need to synthesize descriptions for those aircraft, find all Aircraft that fuzzily match the
|
45
|
+
# synthesized descriptions, and associate those Aircraft with the original aircraft_description.
|
46
|
+
# e.g. boeing 747-100/200
|
47
|
+
if original_description.include?("/")
|
48
|
+
# Pull out the complete first aircraft description
|
49
|
+
# e.g. 'boeing 747-100'
|
50
|
+
first_description = original_description.split('/')[0]
|
51
|
+
|
52
|
+
# Pull out the root of the description - the text up to and including the last ' ' or '-'
|
53
|
+
# e.g. 'boeing 747-'
|
54
|
+
root_length = first_description.rindex(/[ \-]/)
|
55
|
+
root = first_description.slice(0..root_length)
|
56
|
+
|
57
|
+
# Pull out the suffixes - the text separated by forward slashes
|
58
|
+
# e.g. ['100', '200']
|
59
|
+
suffixes = original_description.split(root)[1].split('/')
|
60
|
+
|
61
|
+
# Create an array of synthesized descriptions by appending each suffix to the root
|
62
|
+
# e.g. ['boeing 747-100', 'boeing 747-200']
|
63
|
+
suffixes.map{ |suffix| root + suffix }.each do |synthesized_description|
|
64
|
+
# Look up the Aircraft that match each synthesized description and associate
|
65
|
+
# them with the original flight segment aircraft_description
|
66
|
+
Aircraft.loose_tight_dictionary.find_all(synthesized_description).each do |aircraft|
|
67
|
+
attrs = {
|
68
|
+
:a_class => "Aircraft",
|
69
|
+
:a => aircraft.description,
|
70
|
+
:b_class => "FlightSegment",
|
71
|
+
:b => original_description
|
72
|
+
}
|
73
|
+
unless ::LooseTightDictionary::CachedResult.exists? attrs
|
74
|
+
::LooseTightDictionary::CachedResult.create! attrs
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
# If the flight segment's aircraft_description doesn't contain '/' we can use
|
79
|
+
# a method provided by loose_tight_dictionary to associate it with Aircraft
|
80
|
+
else
|
81
|
+
flight_segment.cache_aircraft!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
39
86
|
data_miner do
|
40
87
|
('A'..'Z').each do |letter|
|
41
88
|
import("aircraft made by whitelisted manufacturers whose ICAO code starts with '#{letter}' from the FAA",
|
@@ -73,13 +120,13 @@ Aircraft.class_eval do
|
|
73
120
|
end
|
74
121
|
|
75
122
|
process "Synthesize description from manufacturer name and model name" do
|
76
|
-
|
123
|
+
find_each do |aircraft|
|
77
124
|
aircraft.update_attribute :description, [aircraft.manufacturer_name, aircraft.model_name].join(' ').downcase
|
78
125
|
end
|
79
126
|
end
|
80
127
|
|
81
128
|
process "Synthesize class code from engine type and weight class" do
|
82
|
-
|
129
|
+
find_each do |aircraft|
|
83
130
|
size = case aircraft.weight_class
|
84
131
|
when 'Small', 'Small+', 'Light'
|
85
132
|
'Light'
|
@@ -92,67 +139,8 @@ Aircraft.class_eval do
|
|
92
139
|
end
|
93
140
|
end
|
94
141
|
|
95
|
-
process
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
process "Cache fuzzy matches between FlightSegment aircraft_description and Aircraft description" do
|
100
|
-
LooseTightDictionary::CachedResult.setup
|
101
|
-
FlightSegment.find_by_sql("SELECT * FROM flight_segments GROUP BY aircraft_description HAVING aircraft_description IS NOT NULL").each do |flight_segment|
|
102
|
-
original_description = flight_segment.aircraft_description
|
103
|
-
|
104
|
-
# If the flight segment's aircraft_description contains '/' then it describes multiple aircraft.
|
105
|
-
# We need to synthesize descriptions for those aircraft, find all Aircraft that fuzzily match the
|
106
|
-
# synthesized descriptions, and associate those Aircraft with the original aircraft_description.
|
107
|
-
# e.g. boeing 747-100/200
|
108
|
-
if original_description.include?("/")
|
109
|
-
# Pull out the complete first aircraft description
|
110
|
-
# e.g. 'boeing 747-100'
|
111
|
-
first_description = original_description.split('/')[0]
|
112
|
-
|
113
|
-
# Pull out the root of the description - the text up to and including the last ' ' or '-'
|
114
|
-
# e.g. 'boeing 747-'
|
115
|
-
root_length = first_description.rindex(/[ \-]/)
|
116
|
-
root = first_description.slice(0..root_length)
|
117
|
-
|
118
|
-
# Pull out the suffixes - the text separated by forward slashes
|
119
|
-
# e.g. ['100', '200']
|
120
|
-
suffixes = original_description.split(root)[1].split('/')
|
121
|
-
|
122
|
-
# Create an array of synthesized descriptions by appending each suffix to the root
|
123
|
-
# e.g. ['boeing 747-100', 'boeing 747-200']
|
124
|
-
suffixes.map{ |suffix| root + suffix }.each do |synthesized_description|
|
125
|
-
# Look up the Aircraft that match each synthesized description and associate
|
126
|
-
# them with the original flight segment aircraft_description
|
127
|
-
Aircraft.loose_tight_dictionary.find_all(synthesized_description).each do |aircraft|
|
128
|
-
attrs = {
|
129
|
-
:a_class => "Aircraft",
|
130
|
-
:a => aircraft.description,
|
131
|
-
:b_class => "FlightSegment",
|
132
|
-
:b => original_description
|
133
|
-
}
|
134
|
-
unless ::LooseTightDictionary::CachedResult.exists? attrs
|
135
|
-
::LooseTightDictionary::CachedResult.create! attrs
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
# If the flight segment's aircraft_description doesn't contain '/' we can use
|
140
|
-
# a method provided by loose_tight_dictionary to associate it with Aircraft
|
141
|
-
else
|
142
|
-
flight_segment.cache_aircraft!
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
# FIXME TODO do we want to restrict this to certain years?
|
148
|
-
process "Derive some average characteristics from flight segments" do
|
149
|
-
Aircraft.find_each do |aircraft|
|
150
|
-
aircraft.seats = aircraft.flight_segments.weighted_average :seats_per_flight, :weighted_by => :passengers
|
151
|
-
aircraft.passengers = aircraft.flight_segments.sum :passengers
|
152
|
-
aircraft.save
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
142
|
+
process :update_averages!
|
143
|
+
|
156
144
|
# FIXME TODO verify this
|
157
145
|
end
|
158
146
|
end
|
data/lib/earth/air/airline.rb
CHANGED
data/lib/earth/air/airport.rb
CHANGED
@@ -19,7 +19,7 @@ class FlightSegment < ActiveRecord::Base
|
|
19
19
|
:load_factor => lambda { weighted_average(:load_factor, :weighted_by => :passengers) }, # 0.78073233770097 data1 10-12-2010
|
20
20
|
:freight_share => lambda { weighted_average(:freight_share, :weighted_by => :passengers) } # 0.022567224170157 data1 10-12-2010
|
21
21
|
|
22
|
-
|
22
|
+
force_schema do
|
23
23
|
string 'row_hash' # auto-generated primary key
|
24
24
|
string 'origin_airport_iata_code' # iata code
|
25
25
|
string 'origin_airport_city' # city
|
@@ -10,6 +10,24 @@ FlightSegment.class_eval do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.update_averages!
|
14
|
+
# Derive load factor, which is passengers divided by available seats
|
15
|
+
update_all 'load_factor = passengers / seats', 'seats > 0'
|
16
|
+
|
17
|
+
# Assume a load factor of 1 where passengers > available seats
|
18
|
+
update_all 'load_factor = 1', 'passengers > seats AND seats > 0'
|
19
|
+
|
20
|
+
# TODO: what is 90.718474
|
21
|
+
# Derive freight share as a fraction of the total weight carried
|
22
|
+
update_all 'freight_share = (freight + mail) / (freight + mail + (passengers * 90.718474))', '(freight + mail + passengers) > 0'
|
23
|
+
|
24
|
+
# Derive average seats per flight
|
25
|
+
update_all 'seats_per_flight = seats / flights', 'flights > 0'
|
26
|
+
|
27
|
+
# Add a useful date field
|
28
|
+
update_all 'approximate_date = DATE(CONCAT_WS("-", year, month, "14"))', 'month IS NOT NULL'
|
29
|
+
end
|
30
|
+
|
13
31
|
URL = 'http://www.transtats.bts.gov/DownLoad_Table.asp?Table_ID=293&Has_Group=3&Is_Zipped=0'
|
14
32
|
FORM_DATA = %{
|
15
33
|
UserTableName=T_100_Segment__All_Carriers&
|
@@ -201,10 +219,10 @@ FlightSegment.class_eval do
|
|
201
219
|
store 'flights', :field_name => 'DEPARTURES_PERFORMED'
|
202
220
|
store 'passengers', :field_name => 'PASSENGERS'
|
203
221
|
store 'seats', :field_name => 'SEATS'
|
204
|
-
store 'payload_capacity', :field_name => 'PAYLOAD', :
|
205
|
-
store 'freight', :field_name => 'FREIGHT', :
|
206
|
-
store 'mail', :field_name => 'MAIL', :
|
207
|
-
store 'distance', :field_name => 'DISTANCE', :
|
222
|
+
store 'payload_capacity', :field_name => 'PAYLOAD', :from_units => :pounds, :to_units => :kilograms
|
223
|
+
store 'freight', :field_name => 'FREIGHT', :from_units => :pounds, :to_units => :kilograms
|
224
|
+
store 'mail', :field_name => 'MAIL', :from_units => :pounds, :to_units => :kilograms
|
225
|
+
store 'distance', :field_name => 'DISTANCE', :from_units => :miles, :to_units => :kilometres
|
208
226
|
store 'month', :field_name => 'MONTH'
|
209
227
|
store 'year', :field_name => 'YEAR'
|
210
228
|
store 'source', :static => 'BTS T100'
|
@@ -232,49 +250,9 @@ FlightSegment.class_eval do
|
|
232
250
|
end
|
233
251
|
end
|
234
252
|
|
235
|
-
|
236
|
-
process "Convert #{field} from pounds to kilograms" do
|
237
|
-
conversion_factor = 1.pounds.to(:kilograms)
|
238
|
-
connection.execute %{
|
239
|
-
UPDATE flight_segments
|
240
|
-
SET #{field} = #{field} * #{conversion_factor},
|
241
|
-
#{field + '_units'} = 'kilograms'
|
242
|
-
WHERE #{field + '_units'} = 'pounds'
|
243
|
-
}
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
process "Convert distance from miles to kilometres" do
|
248
|
-
conversion_factor = 1.miles.to(:kilometres)
|
249
|
-
connection.execute %{
|
250
|
-
UPDATE flight_segments
|
251
|
-
SET distance = distance * #{conversion_factor},
|
252
|
-
distance_units = 'kilometres'
|
253
|
-
WHERE distance_units = 'miles'
|
254
|
-
}
|
255
|
-
end
|
256
|
-
|
257
|
-
process "Derive load factor, which is passengers divided by available seats" do
|
258
|
-
update_all 'load_factor = passengers / seats', 'seats > 0'
|
259
|
-
end
|
260
|
-
|
261
|
-
process "Assume a load factor of 1 where passengers > available seats" do
|
262
|
-
update_all 'load_factor = 1', 'passengers > seats AND seats > 0'
|
263
|
-
end
|
264
|
-
|
265
|
-
process "Derive freight share as a fraction of the total weight carried" do
|
266
|
-
update_all 'freight_share = (freight + mail) / (freight + mail + (passengers * 90.718474))', '(freight + mail + passengers) > 0'
|
267
|
-
end
|
268
|
-
|
269
|
-
process "Derive average seats per flight" do
|
270
|
-
update_all 'seats_per_flight = seats / flights', 'flights > 0'
|
271
|
-
end
|
272
|
-
|
273
|
-
process "Add a useful date field" do
|
274
|
-
update_all 'approximate_date = DATE(CONCAT_WS("-", year, month, "14"))', 'month IS NOT NULL'
|
275
|
-
end
|
253
|
+
process :update_averages!
|
276
254
|
|
277
|
-
process "Data mine Aircraft
|
255
|
+
process "Data mine Aircraft because it's like a belongs-to association" do
|
278
256
|
Aircraft.run_data_miner!
|
279
257
|
end
|
280
258
|
|
@@ -98,7 +98,7 @@ class AutomobileFuel < ActiveRecord::Base
|
|
98
98
|
:hfc_emission_factor => lambda { AutomobileFuel.fallback_hfc_emission_factor },
|
99
99
|
:hfc_emission_factor_units => lambda { AutomobileFuel.fallback_hfc_emission_factor_units }
|
100
100
|
|
101
|
-
|
101
|
+
force_schema do
|
102
102
|
string 'name'
|
103
103
|
string 'code'
|
104
104
|
string 'base_fuel_name'
|