earth 0.5.2 → 0.5.3
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/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'
|