earth 0.0.18

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.
Files changed (189) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/.rvmrc +8 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +20 -0
  6. data/README.markdown +38 -0
  7. data/Rakefile +71 -0
  8. data/VERSION +1 -0
  9. data/earth.gemspec +265 -0
  10. data/lib/earth.rb +169 -0
  11. data/lib/earth/air.rb +13 -0
  12. data/lib/earth/air/aircraft.rb +32 -0
  13. data/lib/earth/air/aircraft/data_miner.rb +171 -0
  14. data/lib/earth/air/aircraft_class.rb +10 -0
  15. data/lib/earth/air/aircraft_class/data_miner.rb +42 -0
  16. data/lib/earth/air/aircraft_manufacturer.rb +9 -0
  17. data/lib/earth/air/aircraft_manufacturer/data_miner.rb +20 -0
  18. data/lib/earth/air/airline.rb +16 -0
  19. data/lib/earth/air/airline/data_miner.rb +57 -0
  20. data/lib/earth/air/airport.rb +44 -0
  21. data/lib/earth/air/airport/data_miner.rb +80 -0
  22. data/lib/earth/air/data_miner.rb +15 -0
  23. data/lib/earth/air/flight_configuration.rb +18 -0
  24. data/lib/earth/air/flight_configuration/data_miner.rb +4 -0
  25. data/lib/earth/air/flight_distance_class.rb +7 -0
  26. data/lib/earth/air/flight_distance_class/data_miner.rb +16 -0
  27. data/lib/earth/air/flight_domesticity.rb +6 -0
  28. data/lib/earth/air/flight_domesticity/data_miner.rb +57 -0
  29. data/lib/earth/air/flight_fuel_type.rb +17 -0
  30. data/lib/earth/air/flight_fuel_type/data_miner.rb +4 -0
  31. data/lib/earth/air/flight_propulsion.rb +18 -0
  32. data/lib/earth/air/flight_propulsion/data_miner.rb +4 -0
  33. data/lib/earth/air/flight_seat_class.rb +12 -0
  34. data/lib/earth/air/flight_seat_class/data_miner.rb +36 -0
  35. data/lib/earth/air/flight_segment.rb +38 -0
  36. data/lib/earth/air/flight_segment/data_miner.rb +334 -0
  37. data/lib/earth/air/flight_service.rb +18 -0
  38. data/lib/earth/air/flight_service/data_miner.rb +4 -0
  39. data/lib/earth/all.rb +10 -0
  40. data/lib/earth/automobile.rb +8 -0
  41. data/lib/earth/automobile/automobile_fuel_type.rb +18 -0
  42. data/lib/earth/automobile/automobile_fuel_type/data_miner.rb +45 -0
  43. data/lib/earth/automobile/automobile_make.rb +14 -0
  44. data/lib/earth/automobile/automobile_make/data_miner.rb +68 -0
  45. data/lib/earth/automobile/automobile_make_fleet_year.rb +15 -0
  46. data/lib/earth/automobile/automobile_make_fleet_year/data_miner.rb +29 -0
  47. data/lib/earth/automobile/automobile_make_year.rb +14 -0
  48. data/lib/earth/automobile/automobile_make_year/data_miner.rb +45 -0
  49. data/lib/earth/automobile/automobile_model.rb +14 -0
  50. data/lib/earth/automobile/automobile_model/data_miner.rb +38 -0
  51. data/lib/earth/automobile/automobile_model_year.rb +15 -0
  52. data/lib/earth/automobile/automobile_model_year/data_miner.rb +51 -0
  53. data/lib/earth/automobile/automobile_size_class.rb +14 -0
  54. data/lib/earth/automobile/automobile_size_class/data_miner.rb +43 -0
  55. data/lib/earth/automobile/automobile_variant.rb +17 -0
  56. data/lib/earth/automobile/automobile_variant/data_miner.rb +464 -0
  57. data/lib/earth/automobile/data_miner.rb +8 -0
  58. data/lib/earth/bus.rb +1 -0
  59. data/lib/earth/bus/bus_class.rb +19 -0
  60. data/lib/earth/bus/bus_class/data_miner.rb +41 -0
  61. data/lib/earth/bus/data_miner.rb +1 -0
  62. data/lib/earth/conversions_ext.rb +45 -0
  63. data/lib/earth/data_miner.rb +10 -0
  64. data/lib/earth/diet.rb +2 -0
  65. data/lib/earth/diet/data_miner.rb +2 -0
  66. data/lib/earth/diet/diet_class.rb +15 -0
  67. data/lib/earth/diet/diet_class/data_miner.rb +36 -0
  68. data/lib/earth/diet/food_group.rb +17 -0
  69. data/lib/earth/diet/food_group/data_miner.rb +26 -0
  70. data/lib/earth/fuel.rb +2 -0
  71. data/lib/earth/fuel/data_miner.rb +2 -0
  72. data/lib/earth/fuel/fuel_price.rb +13 -0
  73. data/lib/earth/fuel/fuel_price/data_miner.rb +20 -0
  74. data/lib/earth/fuel/fuel_type.rb +18 -0
  75. data/lib/earth/fuel/fuel_type/data_miner.rb +37 -0
  76. data/lib/earth/industry.rb +10 -0
  77. data/lib/earth/industry/data_miner.rb +2 -0
  78. data/lib/earth/industry/industries_product_lines.rb +6 -0
  79. data/lib/earth/industry/industries_sectors.rb +6 -0
  80. data/lib/earth/industry/industry.rb +12 -0
  81. data/lib/earth/industry/industry/data_miner.rb +21 -0
  82. data/lib/earth/industry/merchant.rb +5 -0
  83. data/lib/earth/industry/merchant_categories_industries.rb +8 -0
  84. data/lib/earth/industry/merchant_category.rb +6 -0
  85. data/lib/earth/industry/product_line.rb +10 -0
  86. data/lib/earth/industry/product_line/data_miner.rb +18 -0
  87. data/lib/earth/industry/product_lines_sectors.rb +6 -0
  88. data/lib/earth/industry/sector.rb +3 -0
  89. data/lib/earth/inflectors.rb +9 -0
  90. data/lib/earth/locality.rb +10 -0
  91. data/lib/earth/locality/census_division.rb +17 -0
  92. data/lib/earth/locality/census_division/data_miner.rb +21 -0
  93. data/lib/earth/locality/census_region.rb +13 -0
  94. data/lib/earth/locality/census_region/data_miner.rb +17 -0
  95. data/lib/earth/locality/climate_division.rb +17 -0
  96. data/lib/earth/locality/climate_division/data_miner.rb +20 -0
  97. data/lib/earth/locality/country.rb +13 -0
  98. data/lib/earth/locality/country/data_miner.rb +19 -0
  99. data/lib/earth/locality/data_miner.rb +10 -0
  100. data/lib/earth/locality/egrid_region.rb +15 -0
  101. data/lib/earth/locality/egrid_region/data_miner.rb +19 -0
  102. data/lib/earth/locality/egrid_subregion.rb +16 -0
  103. data/lib/earth/locality/egrid_subregion/data_miner.rb +26 -0
  104. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +13 -0
  105. data/lib/earth/locality/petroleum_administration_for_defense_district/data_miner.rb +21 -0
  106. data/lib/earth/locality/state.rb +22 -0
  107. data/lib/earth/locality/state/data_miner.rb +37 -0
  108. data/lib/earth/locality/urbanity.rb +20 -0
  109. data/lib/earth/locality/urbanity/data_miner.rb +4 -0
  110. data/lib/earth/locality/zip_code.rb +29 -0
  111. data/lib/earth/locality/zip_code/data_miner.rb +36 -0
  112. data/lib/earth/pet.rb +4 -0
  113. data/lib/earth/pet/breed.rb +15 -0
  114. data/lib/earth/pet/breed/data_miner.rb +25 -0
  115. data/lib/earth/pet/breed_gender.rb +14 -0
  116. data/lib/earth/pet/breed_gender/data_miner.rb +21 -0
  117. data/lib/earth/pet/data_miner.rb +4 -0
  118. data/lib/earth/pet/gender.rb +10 -0
  119. data/lib/earth/pet/gender/data_miner.rb +13 -0
  120. data/lib/earth/pet/species.rb +40 -0
  121. data/lib/earth/pet/species/data_miner.rb +42 -0
  122. data/lib/earth/rail.rb +1 -0
  123. data/lib/earth/rail/data_miner.rb +1 -0
  124. data/lib/earth/rail/rail_class.rb +16 -0
  125. data/lib/earth/rail/rail_class/data_miner.rb +36 -0
  126. data/lib/earth/residence.rb +8 -0
  127. data/lib/earth/residence/air_conditioner_use.rb +30 -0
  128. data/lib/earth/residence/air_conditioner_use/data_miner.rb +4 -0
  129. data/lib/earth/residence/clothes_machine_use.rb +33 -0
  130. data/lib/earth/residence/clothes_machine_use/data_miner.rb +4 -0
  131. data/lib/earth/residence/data_miner.rb +8 -0
  132. data/lib/earth/residence/dishwasher_use.rb +33 -0
  133. data/lib/earth/residence/dishwasher_use/data_miner.rb +4 -0
  134. data/lib/earth/residence/residence_appliance.rb +7 -0
  135. data/lib/earth/residence/residence_appliance/data_miner.rb +19 -0
  136. data/lib/earth/residence/residence_class.rb +26 -0
  137. data/lib/earth/residence/residence_class/data_miner.rb +4 -0
  138. data/lib/earth/residence/residence_fuel_price.rb +18 -0
  139. data/lib/earth/residence/residence_fuel_price/data_miner.rb +200 -0
  140. data/lib/earth/residence/residence_fuel_type.rb +33 -0
  141. data/lib/earth/residence/residence_fuel_type/data_miner.rb +18 -0
  142. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +67 -0
  143. data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +264 -0
  144. data/lib/earth/schema.rb +8 -0
  145. data/spec/lib/earth_spec.rb +25 -0
  146. data/spec/spec_helper.rb +11 -0
  147. data/vendor/geokit-rails/CHANGELOG.rdoc +46 -0
  148. data/vendor/geokit-rails/MIT-LICENSE +20 -0
  149. data/vendor/geokit-rails/README.markdown +561 -0
  150. data/vendor/geokit-rails/Rakefile +18 -0
  151. data/vendor/geokit-rails/about.yml +9 -0
  152. data/vendor/geokit-rails/assets/api_keys_template +61 -0
  153. data/vendor/geokit-rails/init.rb +1 -0
  154. data/vendor/geokit-rails/install.rb +14 -0
  155. data/vendor/geokit-rails/lib/geokit-rails.rb +24 -0
  156. data/vendor/geokit-rails/lib/geokit-rails/acts_as_mappable.rb +456 -0
  157. data/vendor/geokit-rails/lib/geokit-rails/adapters/abstract.rb +31 -0
  158. data/vendor/geokit-rails/lib/geokit-rails/adapters/mysql.rb +22 -0
  159. data/vendor/geokit-rails/lib/geokit-rails/adapters/postgresql.rb +22 -0
  160. data/vendor/geokit-rails/lib/geokit-rails/adapters/sqlserver.rb +43 -0
  161. data/vendor/geokit-rails/lib/geokit-rails/defaults.rb +22 -0
  162. data/vendor/geokit-rails/lib/geokit-rails/geocoder_control.rb +16 -0
  163. data/vendor/geokit-rails/lib/geokit-rails/ip_geocode_lookup.rb +46 -0
  164. data/vendor/geokit-rails/test/acts_as_mappable_test.rb +474 -0
  165. data/vendor/geokit-rails/test/boot.rb +25 -0
  166. data/vendor/geokit-rails/test/database.yml +20 -0
  167. data/vendor/geokit-rails/test/fixtures/companies.yml +7 -0
  168. data/vendor/geokit-rails/test/fixtures/custom_locations.yml +54 -0
  169. data/vendor/geokit-rails/test/fixtures/locations.yml +54 -0
  170. data/vendor/geokit-rails/test/fixtures/mock_addresses.yml +17 -0
  171. data/vendor/geokit-rails/test/fixtures/mock_families.yml +2 -0
  172. data/vendor/geokit-rails/test/fixtures/mock_houses.yml +9 -0
  173. data/vendor/geokit-rails/test/fixtures/mock_organizations.yml +5 -0
  174. data/vendor/geokit-rails/test/fixtures/mock_people.yml +5 -0
  175. data/vendor/geokit-rails/test/fixtures/stores.yml +0 -0
  176. data/vendor/geokit-rails/test/ip_geocode_lookup_test.rb +77 -0
  177. data/vendor/geokit-rails/test/models/company.rb +3 -0
  178. data/vendor/geokit-rails/test/models/custom_location.rb +12 -0
  179. data/vendor/geokit-rails/test/models/location.rb +4 -0
  180. data/vendor/geokit-rails/test/models/mock_address.rb +4 -0
  181. data/vendor/geokit-rails/test/models/mock_family.rb +3 -0
  182. data/vendor/geokit-rails/test/models/mock_house.rb +3 -0
  183. data/vendor/geokit-rails/test/models/mock_organization.rb +4 -0
  184. data/vendor/geokit-rails/test/models/mock_person.rb +4 -0
  185. data/vendor/geokit-rails/test/models/store.rb +3 -0
  186. data/vendor/geokit-rails/test/schema.rb +60 -0
  187. data/vendor/geokit-rails/test/tasks.rake +31 -0
  188. data/vendor/geokit-rails/test/test_helper.rb +23 -0
  189. metadata +444 -0
@@ -0,0 +1,14 @@
1
+ class AutomobileMake < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :make_years, :class_name => 'AutomobileMakeYear', :foreign_key => 'make_name'
5
+ has_many :models, :class_name => 'AutomobileModel', :foreign_key => 'make_name'
6
+ has_many :fleet_years, :class_name => 'AutomobileMakeFleetYear', :foreign_key => 'make_name'
7
+ has_many :variants, :class_name => 'AutomobileVariant', :foreign_key => 'make_name'
8
+
9
+ scope :major, :conditions => { :major => true }, :order => :name
10
+
11
+ data_miner do
12
+ tap "Brighter Planet's make year data", Earth.taps_server
13
+ end
14
+ end
@@ -0,0 +1,68 @@
1
+ AutomobileMake.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ connection.drop_table table_name
5
+ end
6
+
7
+ schema Earth.database_options do
8
+ string 'name'
9
+ boolean 'major'
10
+ float 'fuel_efficiency'
11
+ string 'fuel_efficiency_units'
12
+ end
13
+
14
+ process "Derive automobile makes from automobile variants" do
15
+ AutomobileVariant.run_data_miner!
16
+ connection.execute %{
17
+ INSERT IGNORE INTO automobile_makes(name)
18
+ SELECT automobile_variants.make_name FROM automobile_variants WHERE LENGTH(automobile_variants.make_name) > 0
19
+ }
20
+ end
21
+
22
+ import "a Brighter-Planet defined list of major automobile manufacturers",
23
+ :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/makes/make_importance.csv' do
24
+ key 'name'
25
+ store 'major'
26
+ end
27
+
28
+ process "Derive average fuel efficiency from automobile makes and years" do
29
+ AutomobileMakeYear.run_data_miner!
30
+ make_years = AutomobileMakeYear.arel_table
31
+ makes = AutomobileMake.arel_table
32
+ conditional_relation = makes[:name].eq(make_years[:make_name])
33
+ relation = AutomobileMakeYear.weighted_average_relation(:fuel_efficiency, :weighted_by => :volume).where(conditional_relation)
34
+ update_all "fuel_efficiency = (#{relation.to_sql})"
35
+ update_all "fuel_efficiency_units = 'kilometres_per_litre'"
36
+ end
37
+ end
38
+ end
39
+
40
+ # leave this for later if we need it
41
+ # SUBSIDIARIES = {
42
+ # 'Chevrolet' => 'GM',
43
+ # 'Pontiac' => 'GM',
44
+ # 'Audi' => 'Volkswagen',
45
+ # 'Dodge' => 'Chrysler',
46
+ # 'Lincoln' => 'Ford',
47
+ # 'Plymouth' => 'Chrysler',
48
+ # 'Buick' => 'GM',
49
+ # 'Cadillac' => 'GM',
50
+ # 'Merkur' => 'Ford',
51
+ # 'Oldsmobile' => 'GM',
52
+ # 'GMC' => 'GM',
53
+ # 'Bentley' => 'Rolls-Royce', # currently owned by Volkswagen, but a Flying Spur is hardly a rebranded Passat
54
+ # 'Acura' => 'Honda',
55
+ # 'Land Rover' => 'Ford',
56
+ # 'Eagle' => 'Chrysler',
57
+ # 'Geo' => 'GM',
58
+ # 'Laforza' => 'Ford',
59
+ # 'Infiniti' => 'Nissan',
60
+ # 'Lexus' => 'Toyota',
61
+ # 'Saturn' => 'GM',
62
+ # 'Mercury' => 'Ford',
63
+ # 'Alpina' => 'BMW',
64
+ # 'Mini' => 'BMW',
65
+ # 'Maybach' => 'Mercedes',
66
+ # 'Hummer' => 'GM'
67
+ # }
68
+
@@ -0,0 +1,15 @@
1
+ class AutomobileMakeFleetYear < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ belongs_to :make, :class_name => 'AutomobileMake', :foreign_key => 'make_name'
5
+ # WRONG belongs_to :model_year, :class_name => 'AutomobileModelYear', :foreign_key => 'automobile_model_year_name'
6
+ belongs_to :make_year, :class_name => 'AutomobileMakeYear', :foreign_key => 'make_year_name'
7
+
8
+ data_miner do
9
+ tap "Brighter Planet's sanitized auto make fleet year data", Earth.taps_server
10
+
11
+ process "bring in dependencies" do
12
+ run_data_miner_on_belongs_to_associations
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ AutomobileMakeFleetYear.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ string 'make_year_name'
6
+ string 'make_name'
7
+ string 'fleet'
8
+ integer 'year'
9
+ float 'fuel_efficiency'
10
+ string 'fuel_efficiency_units'
11
+ integer 'volume'
12
+ end
13
+
14
+ # CAFE data privately emailed to Andy from Terry Anderson at the DOT/NHTSA
15
+ import "annual corporate average fuel economy data for domestic and imported vehicle fleets from the NHTSA",
16
+ :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/make_fleet_years/make_fleet_years.csv',
17
+ :errata => 'http://static.brighterplanet.com/science/data/transport/automobiles/make_fleet_years/errata.csv',
18
+ :select => lambda { |row| row['volume'].to_i > 0 } do
19
+ key 'name', :synthesize => lambda { |row| [ row['manufacturer_name'], row['year_content'], row['fleet'][2,2] ].join ' ' }
20
+ store 'make_year_name', :synthesize => lambda { |row| [ row['manufacturer_name'], row['year_content'] ].join ' ' }
21
+ store 'make_name', :field_name => 'manufacturer_name'
22
+ store 'year', :field_name => 'year_content'
23
+ store 'fleet', :chars => 2..3 # zero-based
24
+ store 'fuel_efficiency', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
25
+ store 'volume'
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,14 @@
1
+ class AutomobileMakeYear < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ belongs_to :make, :class_name => 'AutomobileMake', :foreign_key => 'make_name'
5
+ has_many :fleet_years, :class_name => 'AutomobileMakeFleetYear', :foreign_key => 'make_year_name'
6
+
7
+ data_miner do
8
+ tap "Brighter Planet's make year data", Earth.taps_server
9
+
10
+ process "bring in dependencies" do
11
+ run_data_miner_on_belongs_to_associations
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,45 @@
1
+ AutomobileMakeYear.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ connection.drop_table table_name
5
+ end
6
+
7
+ schema Earth.database_options do
8
+ string 'name'
9
+ string 'make_name'
10
+ integer 'year'
11
+ float 'fuel_efficiency'
12
+ string 'fuel_efficiency_units'
13
+ integer 'volume'
14
+ end
15
+
16
+ process "Derive manufacturer names and years from automobile make fleet years" do
17
+ AutomobileMakeFleetYear.run_data_miner!
18
+ connection.execute %{
19
+ INSERT IGNORE INTO automobile_make_years(name, make_name, year)
20
+ SELECT
21
+ automobile_make_fleet_years.make_year_name,
22
+ automobile_make_fleet_years.make_name,
23
+ automobile_make_fleet_years.year
24
+ FROM automobile_make_fleet_years
25
+ }
26
+ end
27
+
28
+ process "Derive annual corporate average fuel economy across all vehicles from automobile make fleet years" do
29
+ AutomobileMakeFleetYear.run_data_miner!
30
+ make_fleet_years = AutomobileMakeFleetYear.arel_table
31
+ make_years = AutomobileMakeYear.arel_table
32
+ conditional_relation = make_years[:name].eq(make_fleet_years[:make_year_name])
33
+ relation = AutomobileMakeFleetYear.weighted_average_relation(:fuel_efficiency, :weighted_by => :volume).where(conditional_relation)
34
+ update_all "fuel_efficiency = (#{relation.to_sql})"
35
+ update_all "fuel_efficiency_units = 'kilometres_per_litre'"
36
+ end
37
+
38
+ process "Derive sales volume across all vehicles from automobile make fleet years" do
39
+ connection.execute %{
40
+ UPDATE automobile_make_years SET automobile_make_years.volume = (SELECT SUM(automobile_make_fleet_years.volume) FROM automobile_make_fleet_years WHERE automobile_make_fleet_years.make_year_name = automobile_make_years.name)
41
+ }
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,14 @@
1
+ class AutomobileModel < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :variants, :class_name => 'AutomobileVariant', :foreign_key => 'model_name'
5
+ belongs_to :make, :class_name => 'AutomobileMake', :foreign_key => 'make_name'
6
+
7
+ data_miner do
8
+ tap "Brighter Planet's auto model data", Earth.taps_server
9
+
10
+ process "bring in dependencies" do
11
+ run_data_miner_on_belongs_to_associations
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ AutomobileModel.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ connection.drop_table table_name
5
+ end
6
+
7
+ schema Earth.database_options do
8
+ string 'name' # make + model
9
+ string 'make_name'
10
+ float 'fuel_efficiency_city'
11
+ string 'fuel_efficiency_city_units'
12
+ float 'fuel_efficiency_highway'
13
+ string 'fuel_efficiency_highway_units'
14
+ end
15
+
16
+ process "Derive model names from automobile variants" do
17
+ AutomobileVariant.run_data_miner!
18
+ connection.execute %{
19
+ INSERT IGNORE INTO automobile_models(name, make_name)
20
+ SELECT automobile_variants.model_name, automobile_variants.make_name FROM automobile_variants WHERE LENGTH(automobile_variants.model_name) > 0 AND LENGTH(automobile_variants.make_name) > 0
21
+ }
22
+ end
23
+
24
+ # TODO not weighted until we get weightings on auto variants
25
+ process "Derive average fuel economy from automobile variants" do
26
+ AutomobileVariant.run_data_miner!
27
+ automobile_models = AutomobileModel.arel_table
28
+ automobile_variants = AutomobileVariant.arel_table
29
+ conditional_relation = automobile_models[:name].eq(automobile_variants[:model_name])
30
+ %w{ city highway }.each do |i|
31
+ relation = AutomobileVariant.where(conditional_relation).where("`automobile_variants`.`fuel_efficiency_#{i}` IS NOT NULL").project("AVG(`automobile_variants`.`fuel_efficiency_#{i}`)")
32
+ update_all "fuel_efficiency_#{i} = (#{relation.to_sql})"
33
+ update_all "fuel_efficiency_#{i}_units = 'kilometres_per_litre'"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,15 @@
1
+ class AutomobileModelYear < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ belongs_to :make_year, :class_name => 'AutomobileMakeYear', :foreign_key => 'make_year_name'
5
+ has_many :variants, :class_name => 'AutomobileVariant', :foreign_key => 'model_year_name'
6
+ has_many :automobiles, :foreign_key => 'model_year_id'
7
+
8
+ data_miner do
9
+ tap "Brighter Planet's model year data", Earth.taps_server
10
+
11
+ process "pull dependencies" do
12
+ run_data_miner_on_belongs_to_associations
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ AutomobileModelYear.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ connection.drop_table table_name
5
+ end
6
+
7
+ schema Earth.database_options do
8
+ string 'name'
9
+ string 'make_name'
10
+ string 'model_name'
11
+ integer 'year'
12
+ string 'make_year_name'
13
+ float 'fuel_efficiency'
14
+ string 'fuel_efficiency_units'
15
+ float 'fuel_efficiency_city'
16
+ string 'fuel_efficiency_city_units'
17
+ float 'fuel_efficiency_highway'
18
+ string 'fuel_efficiency_highway_units'
19
+ end
20
+
21
+ process "Derive model year names from automobile variants" do
22
+ AutomobileVariant.run_data_miner!
23
+ connection.execute %{
24
+ INSERT IGNORE INTO automobile_model_years(name, make_name, model_name, year, make_year_name)
25
+ SELECT automobile_variants.model_year_name, automobile_variants.make_name, automobile_variants.model_name, automobile_variants.year, automobile_variants.make_year_name FROM automobile_variants WHERE LENGTH(automobile_variants.make_name) > 0 AND LENGTH(automobile_variants.model_name) > 0
26
+ }
27
+ end
28
+
29
+ # TODO: weight by volume somehow
30
+ # note that we used to derive averages from make years, but here we get it from variants
31
+ # even without volume-weighting, the values are much better.
32
+ # for example, 20km/l for a toyota prius 2006 vs. 13km/l if you use make years
33
+ process "Calculate city and highway fuel efficiency from automobile variants" do
34
+ AutomobileVariant.run_data_miner!
35
+ automobile_model_years = AutomobileModelYear.arel_table
36
+ automobile_variants = AutomobileVariant.arel_table
37
+ conditional_relation = automobile_model_years[:name].eq(automobile_variants[:model_year_name])
38
+ %w{ city highway }.each do |i|
39
+ relation = AutomobileVariant.where(conditional_relation).where("`automobile_variants`.`fuel_efficiency_#{i}` IS NOT NULL").project("AVG(`automobile_variants`.`fuel_efficiency_#{i}`)")
40
+ update_all "fuel_efficiency_#{i} = (#{relation.to_sql})"
41
+ update_all "fuel_efficiency_#{i}_units = 'kilometres_per_litre'"
42
+ end
43
+ end
44
+
45
+ process "Calculate overall fuel efficiency using the latest EPA equation" do
46
+ update_all "fuel_efficiency = 1 / ((0.43 / fuel_efficiency_city) + (0.57 / fuel_efficiency_highway))"
47
+ update_all "fuel_efficiency_units = 'kilometres_per_litre'"
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,14 @@
1
+ class AutomobileSizeClass < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :automobiles, :foreign_key => 'size_class_id'
5
+
6
+ falls_back_on :hybrid_fuel_efficiency_city_multiplier => 1.651, # https://brighterplanet.sifterapp.com/issue/667
7
+ :hybrid_fuel_efficiency_highway_multiplier => 1.213,
8
+ :conventional_fuel_efficiency_city_multiplier => 0.987,
9
+ :conventional_fuel_efficiency_highway_multiplier => 0.996
10
+
11
+ data_miner do
12
+ tap "Brighter Planet's sanitized automobile size class data", Earth.taps_server
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ AutomobileSizeClass.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ float 'fuel_efficiency_city'
6
+ string 'fuel_efficiency_city_units'
7
+ float 'fuel_efficiency_highway'
8
+ string 'fuel_efficiency_highway_units'
9
+ float 'annual_distance'
10
+ string 'annual_distance_units'
11
+ string 'emblem'
12
+ float 'hybrid_fuel_efficiency_city_multiplier'
13
+ float 'hybrid_fuel_efficiency_highway_multiplier'
14
+ float 'conventional_fuel_efficiency_city_multiplier'
15
+ float 'conventional_fuel_efficiency_highway_multiplier'
16
+ end
17
+
18
+ import "a list of size classes and pre-calculated annual distances and fuel efficiencies",
19
+ :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/models_export/automobile_size_class.csv' do
20
+ key 'name'
21
+ store 'annual_distance', :units => :kilometres
22
+ store 'fuel_efficiency_city', :units => :kilometres_per_litre
23
+ store 'fuel_efficiency_highway', :units => :kilometres_per_litre
24
+ end
25
+
26
+ # Ian 5/27/2010 I'm pretty sure we don't need emblems in middleware
27
+ # import "",
28
+ # :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/models_export/automobile_size_class_emblems.csv' do
29
+ # key 'name'
30
+ # store 'emblem'
31
+ # end
32
+
33
+ import "pre-calculated hybridity multipliers",
34
+ :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/vehicle_classes/fuel_efficiency_multipliers.csv' do
35
+ key 'name'
36
+ store 'hybrid_fuel_efficiency_city_multiplier'
37
+ store 'hybrid_fuel_efficiency_highway_multiplier'
38
+ store 'conventional_fuel_efficiency_city_multiplier'
39
+ store 'conventional_fuel_efficiency_highway_multiplier'
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,17 @@
1
+ class AutomobileVariant < ActiveRecord::Base
2
+ set_primary_key :row_hash
3
+
4
+ has_many :automobiles, :foreign_key => 'variant_id'
5
+ belongs_to :make, :class_name => 'AutomobileMake', :foreign_key => 'make_name'
6
+ belongs_to :model, :class_name => 'AutomobileModel', :foreign_key => 'model_name'
7
+ belongs_to :model_year, :class_name => 'AutomobileModelYear', :foreign_key => 'model_year_name'
8
+ belongs_to :fuel_type, :class_name => 'AutomobileFuelType', :foreign_key => 'fuel_type_code'
9
+
10
+ data_miner do
11
+ tap "Brighter Planet's sanitized automobile variant data", Earth.taps_server
12
+
13
+ process "pull dependencies" do
14
+ run_data_miner_on_belongs_to_associations
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,464 @@
1
+ AutomobileVariant.class_eval do
2
+ class << self
3
+ def transmission_is_blank?(row)
4
+ row['transmission'].blank?
5
+ end
6
+
7
+ def is_a_2007_gmc_or_chevrolet?(row)
8
+ row['year'] == 2007 and %w(GMC CHEVROLET).include? row['MFR'].upcase
9
+ end
10
+
11
+ def is_a_porsche?(row)
12
+ row['make'].upcase == 'PORSCHE'
13
+ end
14
+
15
+ def is_not_a_porsche?(row)
16
+ !is_a_porsche? row
17
+ end
18
+
19
+ def is_a_mercedes_benz?(row)
20
+ row['make'] =~ /MERCEDES/i
21
+ end
22
+
23
+ def is_a_lexus?(row)
24
+ row['make'].upcase == 'LEXUS'
25
+ end
26
+
27
+ def is_a_bmw?(row)
28
+ row['make'].upcase == 'BMW'
29
+ end
30
+
31
+ def is_a_ford?(row)
32
+ row['make'].upcase == 'FORD'
33
+ end
34
+
35
+ def is_a_rolls_royce_and_model_contains_bentley?(row)
36
+ is_a_rolls_royce?(row) and model_contains_bentley?(row)
37
+ end
38
+
39
+ def is_a_bentley?(row)
40
+ row['make'].upcase == 'BENTLEY'
41
+ end
42
+
43
+ def is_a_rolls_royce?(row)
44
+ row['make'] =~ /ROLLS/i
45
+ end
46
+
47
+ def is_a_turbo_brooklands?(row)
48
+ row['model'] =~ /TURBO R\/RL BKLDS/i
49
+ end
50
+
51
+ def model_contains_maybach?(row)
52
+ row['model'] =~ /MAYBACH/i
53
+ end
54
+
55
+ def model_contains_bentley?(row)
56
+ row['model'] =~ /BENTLEY/i
57
+ end
58
+
59
+ def source_code
60
+ IO.read __FILE__
61
+ end
62
+ end
63
+
64
+ # updated with 2010 names
65
+ TRANSMISSIONS = {
66
+ 'A' => 'Automatic', # prefix
67
+ 'M' => 'Manual', # prefix
68
+ 'L' => 'Automatic', # prefix
69
+ 'S' => 'Semi-Automatic', # prefix
70
+ 'AM' => 'Automated Manual',
71
+ 'C' => 'Continuously Variable',
72
+ 'SA' => 'Semi-Automatic',
73
+ 'CVT' => 'Continuously Variable',
74
+ 'OT' => 'Other'
75
+ }
76
+
77
+ ENGINE_TYPES = {
78
+ '(GUZZLER)' => nil, # "gas guzzler"
79
+ '(POLICE)' => nil, # police automobile_variant
80
+ '(MPFI)' => 'injection',
81
+ '(MPI*)' => 'injection',
82
+ '(SPFI)' => 'injection',
83
+ '(FFS)' => 'injection',
84
+ '(TURBO)' => 'turbo',
85
+ '(TRBO)' => 'turbo',
86
+ '(TC*)' => 'turbo',
87
+ '(FFS,TRBO)' => %w(injection turbo),
88
+ '(S-CHARGE)' => 'supercharger',
89
+ '(SC*)' => 'supercharger',
90
+ '(DIESEL)' => nil, # diesel
91
+ '(DSL)' => nil, # diesel
92
+ '(ROTARY)' => nil, # rotary
93
+ '(VARIABLE)' => nil, # variable displacement
94
+ '(NO-CAT)' => nil, # no catalytic converter
95
+ '(OHC)' => nil, # overhead camshaft
96
+ '(OHV)' => nil, # overhead valves
97
+ '(16-VALVE)' => nil, # 16V
98
+ '(305)' => nil, # 305 cubic inch displacement
99
+ '(307)' => nil, # 307 cubic inch displacement
100
+ '(M-ENG)' => nil,
101
+ '(W-ENG)' => nil,
102
+ '(GM-BUICK)' => nil,
103
+ '(GM-CHEV)' => nil,
104
+ '(GM-OLDS)' => nil,
105
+ '(GM-PONT)' => nil,
106
+ }
107
+
108
+ class AutomobileVariant::ParserB
109
+ attr_accessor :year
110
+ def initialize(options = {})
111
+ @year = options[:year]
112
+ end
113
+
114
+ def apply(row)
115
+ row.merge!({
116
+ 'make' => row['carline_mfr_name'], # make it line up with the errata
117
+ 'model' => row['carline_name'], # ditto
118
+ 'transmission' => TRANSMISSIONS[row['model_trans'][0, 1]],
119
+ 'speeds' => (row['model_trans'][1, 1] == 'V') ? 'variable' : row['model_trans'][1, 1],
120
+ 'turbo' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('turbo'),
121
+ 'supercharger' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('supercharger'),
122
+ 'injection' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('injection'),
123
+ 'displacement' => _displacement(row['opt_disp']),
124
+ 'year' => year
125
+ })
126
+ row
127
+ end
128
+
129
+ def _displacement(str)
130
+ str = str.gsub(/[\(\)]/, '').strip
131
+ if str =~ /^(.+)L$/
132
+ $1.to_f
133
+ elsif str =~ /^(.+)CC$/
134
+ $1.to_f / 1000
135
+ end
136
+ end
137
+
138
+ def add_hints!(bus)
139
+ bus[:format] = :fixed_width
140
+ bus[:cut] = '13-' if year == 1995
141
+ bus[:schema_name] = :fuel_economy_guide_b
142
+ bus[:select] = lambda { |row| row['supress_code'].blank? and row['state_code'] == 'F' }
143
+ Slither.define :fuel_economy_guide_b do |d|
144
+ d.rows do |row|
145
+ row.trap { true } # there's only one section
146
+ row.column 'active_year' , 4, :type => :integer # ACTIVE YEAR
147
+ row.column 'state_code' , 1, :type => :string # STATE CODE: F=49-STATE,C=CALIFORNIA
148
+ row.column 'carline_clss' , 2, :type => :integer # CARLINE CLASS CODE
149
+ row.column 'carline_mfr_code' , 3, :type => :integer # CARLINE MANUFACTURER CODE
150
+ row.column 'carline_name' , 28, :type => :string # CARLINE NAME
151
+ row.column 'disp_cub_in' , 4, :type => :integer # DISP CUBIC INCHES
152
+ row.column 'fuel_system' , 2, :type => :string # FUEL SYSTEM: 'FI' FOR FUEL INJECTION, 2-DIGIT INTEGER VALUE FOR #OF VENTURIES IF CARBURETOR SYSTEM.
153
+ row.column 'model_trans' , 6, :type => :string # TRANSMISSION TYPE
154
+ row.column 'no_cyc' , 2, :type => :integer # NUMBER OF ENGINE CYLINDERS
155
+ row.column 'date_time' , 12, :type => :string # DATE AND TIME RECORD ENTERED -YYMMDDHHMMSS (YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)
156
+ row.column 'release_date' , 6, :type => :string # RELEASE DATE - YYMMDD (YEAR, MONTH, DAY)
157
+ row.column 'vi_mfr_code' , 3, :type => :integer # VI MANUFACTURER CODE
158
+ row.column 'carline_code' , 5, :type => :integer # CARLINE CODE
159
+ row.column 'basic_eng_id' , 5, :type => :integer # BASIC ENGINE INDEX
160
+ row.column 'carline_mfr_name' , 32, :type => :string # CARLINE MANUFACTURER NAME
161
+ row.column 'suppress_code' , 1, :type => :integer # SUPPRESSION CODE (NO SUPPRESSED RECORD IF FOR PUBLIC ACCESS)
162
+ row.column 'est_city_mpg' , 3, :type => :integer # ESTIMATED (CITY) MILES PER GALLON - 90% OF UNADJUSTED VALUE
163
+ row.spacer 2
164
+ row.column 'highway_mpg' , 3, :type => :integer # ESTIMATED (HWY) MILES PER GALLON - 78% OF UNADJUSTED VALUE
165
+ row.spacer 2
166
+ row.column 'combined_mpg' , 3, :type => :integer # COMBINED MILES PER GALLON
167
+ row.spacer 2
168
+ row.column 'unadj_city_mpg' , 3, :type => :integer # UNADJUSTED CITY MILES PER GALLON
169
+ row.spacer 2
170
+ row.column 'unadj_hwy_mpg' , 3, :type => :integer # UNADJUSTED HIGHWAY MILES PER GALLON
171
+ row.spacer 2
172
+ row.column 'unadj_comb_mpg' , 3, :type => :integer # UNADJUSTED COMBINED MILES PER GALLON
173
+ row.spacer 2
174
+ row.column 'ave_anl_fuel' , 6, :type => :integer # "$" in col 147, Annual Fuel Cost starting col 148 in I5
175
+ row.column 'opt_disp' , 8, :type => :string # OPTIONAL DISPLACEMENT
176
+ row.column 'engine_desc1' , 10, :type => :string # ENGINE DESCRIPTION 1
177
+ row.column 'engine_desc2' , 10, :type => :string # ENGINE DESCRIPTION 2
178
+ row.column 'engine_desc3' , 10, :type => :string # ENGINE DESCRIPTION 3
179
+ row.column 'body_type_2d' , 10, :type => :string # BODY TYPE 2 DOOR - IF THE BODY TYPE APPLIES IT WILL TAKE THE FORM '2DR-PPP/LL' WHERE PPP=PASSENGER INTERIOR VOLUME AND LL=LUGGAGE INTERIOR VOLUME.
180
+ row.column 'body_type_4d' , 10, :type => :string # BODY TYPE 4 DOOR - IF THE BODY TYPE APPLIES IT WILL TAKE THE FORM '4DR-PPP/LL' WHERE PPP=PASSENGER INTERIOR VOLUME AND LL=LUGGAGE INTERIOR VOLUME.
181
+ row.column 'body_type_hbk' , 10, :type => :string # BODY TYPE HBK - IF THE BODY TYPE APPLIES IT WILL TAKE THE FORM 'HBK-PPP/LL' WHERE PPP=PASSENGER INTERIOR VOLUME AND LL=LUGGAGE INTERIOR VOLUME.
182
+ row.column 'puerto_rico' , 1, :type => :string # '*' IF FOR PUERTO RICO SALES ONLY
183
+ row.column 'overdrive' , 4, :type => :string # OVERDRIVE: ' OD ' FOR OVERDRIVE, 'EOD ' FOR ELECTRICALLY OPERATED OVERDRIVE AND 'AEOD' FOR AUTOMATIC OVERDRIVE
184
+ row.column 'drive_system' , 3, :type => :string # FWD=FRONT WHEEL DRIVE, RWD=REAR, 4WD=4-WHEEL
185
+ row.column 'filler' , 1, :type => :string # NOT USED
186
+ row.column 'fuel_type' , 1, :type => :string # R=REGULAR(UNLEADED), P=PREMIUM, D=DIESEL
187
+ row.column 'trans_desc' , 15, :type => :string # TRANSMISSION DESCRIPTORS
188
+ end
189
+ end
190
+ end
191
+ end
192
+ class AutomobileVariant::ParserC
193
+ attr_accessor :year
194
+ def initialize(options = {})
195
+ @year = options[:year]
196
+ end
197
+
198
+ def add_hints!(bus)
199
+ # File will decide format based on filename
200
+ end
201
+
202
+ def apply(row)
203
+ row.merge!({
204
+ 'make' => row['Manufacturer'], # make it line up with the errata
205
+ 'model' => row['carline name'], # ditto
206
+ 'drive' => row['drv'] + 'WD',
207
+ 'transmission' => TRANSMISSIONS[row['trans'][-3, 1]], # only using prefix, probably a FIXME
208
+ 'speeds' => (row['trans'][-2, 1] == 'V') ? '1' : row['trans'][-2, 1],
209
+ 'turbo' => row['T'] == 'T',
210
+ 'supercharger' => row['S'] == 'S',
211
+ 'injection' => true,
212
+ 'year' => year
213
+ })
214
+ row
215
+ end
216
+ end
217
+ class AutomobileVariant::ParserD
218
+ attr_accessor :year
219
+ def initialize(options = {})
220
+ @year = options[:year]
221
+ end
222
+
223
+ def add_hints!(bus)
224
+ end
225
+
226
+ def apply(row)
227
+ row.merge!({
228
+ 'make' => row['MFR'], # make it line up with the errata
229
+ 'model' => row['CAR LINE'], # ditto
230
+ 'drive' => row['DRIVE SYS'] + 'WD',
231
+ 'transmission' => TRANSMISSIONS[row['TRANS'][-3, 1]], # only using prefix, probably a FIXME
232
+ 'speeds' => (row['TRANS'][-2, 1] == 'V') ? '1' : row['TRANS'][-2, 1],
233
+ 'turbo' => row['TURBO'] == 'T',
234
+ 'supercharger' => row['SPCHGR'] == 'S',
235
+ 'injection' => true,
236
+ 'year' => year
237
+ })
238
+ row
239
+ end
240
+ end
241
+ class AutomobileVariant::ParserE
242
+ OLD_FUEL_CODES = {
243
+ 'CNG' => 'C',
244
+ 'DU' => 'D',
245
+ 'G' => 'R',
246
+ 'GP' => 'P',
247
+ 'GPR' => 'P'
248
+ }
249
+
250
+ attr_accessor :year
251
+ def initialize(options = {})
252
+ @year = options[:year]
253
+ end
254
+
255
+ def add_hints!(bus)
256
+ end
257
+
258
+ def apply(row)
259
+ row.merge!({
260
+ 'make' => row['Division'], # make it line up with the errata
261
+ 'model' => row['Carline'], # ditto
262
+ 'drive' => row['Drive Sys'] + 'WD',
263
+ 'transmission' => TRANSMISSIONS[row['Trans']],
264
+ 'speeds' => row['# Gears'],
265
+ 'turbo' => row['Air Aspir Method'] == 'TC',
266
+ 'supercharger' => row['Air Aspir Method'] == 'SC',
267
+ 'injection' => true,
268
+ 'year' => year,
269
+ 'fuel_type_code' => OLD_FUEL_CODES[row['Fuel Usage - Conventional Fuel']]
270
+ })
271
+ row
272
+ end
273
+ end
274
+
275
+ data_miner do
276
+ process "Don't re-import too often" do
277
+ raise DataMiner::Skip unless DataMiner::Run.allowed? AutomobileVariant
278
+ end
279
+
280
+ schema Earth.database_options do
281
+ string 'row_hash'
282
+ string 'name' # short name!
283
+ string 'make_name'
284
+ string 'model_name' # make + model
285
+ string 'make_year_name' # make + year
286
+ string 'model_year_name' # make + model + year
287
+ integer 'year'
288
+ float 'fuel_efficiency_city'
289
+ string 'fuel_efficiency_city_units'
290
+ float 'fuel_efficiency_highway'
291
+ string 'fuel_efficiency_highway_units'
292
+ string 'fuel_type_code'
293
+ string 'transmission'
294
+ string 'drive'
295
+ boolean 'turbo'
296
+ boolean 'supercharger'
297
+ integer 'cylinders'
298
+ float 'displacement'
299
+ float 'raw_fuel_efficiency_city'
300
+ string 'raw_fuel_efficiency_city_units'
301
+ float 'raw_fuel_efficiency_highway'
302
+ string 'raw_fuel_efficiency_highway_units'
303
+ integer 'carline_mfr_code'
304
+ integer 'vi_mfr_code'
305
+ integer 'carline_code'
306
+ integer 'carline_class_code'
307
+ boolean 'injection'
308
+ string 'carline_class_name'
309
+ string 'speeds'
310
+ index 'make_name'
311
+ index 'model_name'
312
+ index 'make_year_name'
313
+ index 'model_year_name'
314
+ end
315
+
316
+ # # 1985---1997
317
+ (85..97).each do |yy|
318
+ filename = (yy == 96) ? "#{yy}MFGUI.ASC" : "#{yy}MFGUI.DAT"
319
+ import("19#{ yy } Fuel Economy Guide",
320
+ :url => "http://www.fueleconomy.gov/FEG/epadata/#{yy}mfgui.zip",
321
+ :filename => filename,
322
+ :transform => { :class => AutomobileVariant::ParserB, :year => "19#{yy}".to_i },
323
+ :errata => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/errata.csv') do
324
+ key 'row_hash'
325
+ store 'name', :field_name => 'model'
326
+ store 'make_name', :field_name => 'make'
327
+ store 'year'
328
+ store 'fuel_type_code', :field_name => 'fuel_type'
329
+ store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
330
+ store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
331
+ store 'raw_fuel_efficiency_highway', :field_name => 'unadj_hwy_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
332
+ store 'raw_fuel_efficiency_city', :field_name => 'unadj_city_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
333
+ store 'cylinders', :field_name => 'no_cyc'
334
+ store 'drive', :field_name => 'drive_system'
335
+ store 'carline_mfr_code'
336
+ store 'vi_mfr_code'
337
+ store 'carline_code'
338
+ store 'carline_class_code', :field_name => 'carline_clss'
339
+ store 'transmission'
340
+ store 'speeds'
341
+ store 'turbo'
342
+ store 'supercharger'
343
+ store 'injection'
344
+ store 'displacement'
345
+ end
346
+ end
347
+
348
+ # 1998--2005
349
+ {
350
+ 1998 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/98guide6.zip', :filename => '98guide6.csv' },
351
+ 1999 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/99guide.zip', :filename => '99guide6.csv' },
352
+ 2000 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/00data.zip', :filename => 'G6080900.xls' },
353
+ 2001 => { :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/01guide0918.csv' }, # parseexcel 0.5.2 can't read Excel 5.0 { :url => 'http://www.fueleconomy.gov/FEG/epadata/01data.zip', :filename => '01guide0918.xls' }
354
+ 2002 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/02data.zip', :filename => 'guide_jan28.xls' },
355
+ 2003 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/03data.zip', :filename => 'guide_2003_feb04-03b.csv' },
356
+ 2004 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/04data.zip', :filename => 'gd04-Feb1804-RelDtFeb20.csv' },
357
+ 2005 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/05data.zip', :filename => 'guide2005-2004oct15.csv' }
358
+ }.sort { |a, b| a.first <=> b.first }.each do |year, options|
359
+ import "#{ year } Fuel Economy Guide",
360
+ options.merge(:transform => { :class => AutomobileVariant::ParserC, :year => year },
361
+ :errata => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/errata.csv') do
362
+ key 'row_hash'
363
+ store 'name', :field_name => 'model'
364
+ store 'make_name', :field_name => 'make'
365
+ store 'fuel_type_code', :field_name => 'fl'
366
+ store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
367
+ store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
368
+ store 'raw_fuel_efficiency_highway', :field_name => 'uhwy', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
369
+ store 'raw_fuel_efficiency_city', :field_name => 'ucty', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
370
+ store 'cylinders', :field_name => 'cyl'
371
+ store 'displacement', :field_name => 'displ'
372
+ store 'carline_class_code', :field_name => 'cls' if year >= 2000
373
+ store 'carline_class_name', :field_name => 'Class'
374
+ store 'year'
375
+ store 'transmission'
376
+ store 'speeds'
377
+ store 'turbo'
378
+ store 'supercharger'
379
+ store 'injection'
380
+ store 'drive'
381
+ end
382
+ end
383
+
384
+ # 2006--2009
385
+ {
386
+ 2006 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/06data.zip', :filename => '2006_FE_Guide_14-Nov-2005_download.csv' },
387
+ 2007 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/07data.zip', :filename => '2007_FE_guide_ALL_no_sales_May_01_2007.xls' },
388
+ 2008 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/08data.zip', :filename => '2008_FE_guide_ALL_rel_dates_-no sales-for DOE-5-1-08.csv' },
389
+ 2009 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/09data.zip', :filename => '2009_FE_guide for DOE_ALL-rel dates-no-sales-8-28-08download.csv' },
390
+ }.sort { |a, b| a.first <=> b.first }.each do |year, options|
391
+ import "#{ year } Fuel Economy Guide",
392
+ options.merge(:transform => { :class => AutomobileVariant::ParserD, :year => year },
393
+ :errata => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/errata.csv') do
394
+ key 'row_hash'
395
+ store 'name', :field_name => 'model'
396
+ store 'make_name', :field_name => 'make'
397
+ store 'fuel_type_code', :field_name => 'FUEL TYPE'
398
+ store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
399
+ store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
400
+ store 'raw_fuel_efficiency_highway', :field_name => 'UNRND HWY (EPA)', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
401
+ store 'raw_fuel_efficiency_city', :field_name => 'UNRND CITY (EPA)', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
402
+ store 'cylinders', :field_name => 'NUMB CYL'
403
+ store 'displacement', :field_name => 'DISPLACEMENT'
404
+ store 'carline_class_code', :field_name => 'CLS'
405
+ store 'carline_class_name', :field_name => 'CLASS'
406
+ store 'year'
407
+ store 'transmission'
408
+ store 'speeds'
409
+ store 'turbo'
410
+ store 'supercharger'
411
+ store 'injection'
412
+ store 'drive'
413
+ end
414
+ end
415
+
416
+ # 2010--?
417
+ # sabshere 5/17/10 apparently needs update
418
+ # {
419
+ # 2010 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/10data.zip', :filename => '2010FEguide-for DOE-rel dates before 10-16-09-no-sales10-8-09public.xls' }
420
+ # }.sort { |a, b| a.first <=> b.first }.each do |year, options|
421
+ # import "#{ year } Fuel Economy Guide",
422
+ # options.merge(:transform => { :class => AutomobileVariant::ParserE, :year => year },
423
+ # :errata => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/errata.csv') do
424
+ # key 'row_hash'
425
+ # store 'name', :field_name => 'model'
426
+ # store 'make_name', :field_name => 'make'
427
+ # store 'fuel_type_code'
428
+ # store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
429
+ # store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
430
+ # store 'raw_fuel_efficiency_highway', :field_name => 'Hwy Unadj FE - Conventional Fuel', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
431
+ # store 'raw_fuel_efficiency_city', :field_name => 'City Unadj FE - Conventional Fuel', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
432
+ # store 'cylinders', :field_name => '# Cyl'
433
+ # store 'displacement', :field_name => 'Eng Displ'
434
+ # store 'carline_class_code', :field_name => 'Carline Class'
435
+ # store 'carline_class_name', :field_name => 'Carline Class Desc'
436
+ # store 'year'
437
+ # store 'transmission'
438
+ # store 'speeds'
439
+ # store 'turbo'
440
+ # store 'supercharger'
441
+ # store 'injection'
442
+ # store 'drive'
443
+ # end
444
+ # end
445
+
446
+ process "Derive model and model year names" do
447
+ update_all "model_name = CONCAT(make_name, ' ', name)"
448
+ update_all "make_year_name = CONCAT(make_name, ' ', year)"
449
+ update_all "model_year_name = CONCAT(make_name, ' ', name, ' ', year)"
450
+ end
451
+
452
+ process "Calculate adjusted fuel efficiency using the latest EPA equations" do
453
+ update_all 'fuel_efficiency_city = 1 / ((0.003259 / 0.425143707) + (1.1805 / raw_fuel_efficiency_city))'
454
+ update_all 'fuel_efficiency_highway = 1 / ((0.001376 / 0.425143707) + (1.3466 / raw_fuel_efficiency_highway))'
455
+ end
456
+
457
+ [ AutomobileMake, AutomobileModelYear, AutomobileModel ].each do |synthetic_resource|
458
+ process "Synthesize #{synthetic_resource}" do
459
+ synthetic_resource.run_data_miner!
460
+ end
461
+ end
462
+ end
463
+ end
464
+