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
data/lib/earth.rb ADDED
@@ -0,0 +1,169 @@
1
+ require 'active_record'
2
+ require 'cohort_scope'
3
+ require 'earth/conversions_ext'
4
+ require 'earth/inflectors'
5
+ require 'data_miner'
6
+ require 'falls_back_on'
7
+ require 'falls_back_on/active_record_ext'
8
+
9
+ # The earth module is an interface for establishing a taps server (used to fetch
10
+ # data) and for loading data models from various domains.
11
+ module Earth
12
+ extend self
13
+
14
+ def taps_server
15
+ if defined?(@taps_server)
16
+ @taps_server
17
+ else
18
+ @taps_server = nil
19
+ end
20
+ end
21
+
22
+ # taps_server is a URL. See the data_miner gem docs
23
+ def taps_server=(val)
24
+ @taps_server = val
25
+ end
26
+
27
+ def classes
28
+ [
29
+ AirConditionerUse,
30
+ Aircraft,
31
+ AircraftClass,
32
+ AircraftManufacturer,
33
+ Airline,
34
+ Airport,
35
+ AutomobileFuelType,
36
+ AutomobileMake,
37
+ AutomobileMakeFleetYear,
38
+ AutomobileMakeYear,
39
+ AutomobileModel,
40
+ AutomobileModelYear,
41
+ AutomobileSizeClass,
42
+ AutomobileVariant,
43
+ Breed,
44
+ BreedGender,
45
+ BusClass,
46
+ CensusDivision,
47
+ CensusRegion,
48
+ ClimateDivision,
49
+ ClothesMachineUse,
50
+ Country,
51
+ DietClass,
52
+ DishwasherUse,
53
+ EgridRegion,
54
+ EgridSubregion,
55
+ FlightConfiguration,
56
+ FlightDistanceClass,
57
+ FlightDomesticity,
58
+ FlightFuelType,
59
+ FlightPropulsion,
60
+ FlightSeatClass,
61
+ FlightSegment,
62
+ FlightService,
63
+ FoodGroup,
64
+ Gender,
65
+ PetroleumAdministrationForDefenseDistrict,
66
+ RailClass,
67
+ ResidenceAppliance,
68
+ ResidenceClass,
69
+ ResidenceFuelPrice,
70
+ ResidenceFuelType,
71
+ ResidentialEnergyConsumptionSurveyResponse,
72
+ Species,
73
+ State,
74
+ Urbanity,
75
+ ZipCode
76
+ ]
77
+ end
78
+
79
+ def root
80
+ File.join(File.dirname(__FILE__), '..')
81
+ end
82
+
83
+ def domains
84
+ %w{air automobile bus diet fuel locality pet rail residence}
85
+ end
86
+
87
+ # Earth.init will load any specified domains, any needed ActiveRecord plugins,
88
+ # and will apply each domain model's schema to the database if the
89
+ # :apply_schemas option is given. See Earth.domains for the list of allowable
90
+ # domains.
91
+ #
92
+ # Earth.init should be performed after a connection is made to the database and
93
+ # before any domain models are referenced.
94
+ def init(*args)
95
+ load_plugins
96
+
97
+ domains = []
98
+ options = {}
99
+ args.each do |arg|
100
+ if arg.is_a?(Hash)
101
+ options = arg
102
+ else
103
+ domains << arg
104
+ end
105
+ end
106
+
107
+ load_domains(domains, options)
108
+ load_schemas if options[:apply_schemas]
109
+ end
110
+
111
+ def database_options
112
+ if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite'
113
+ {}
114
+ else
115
+ { :options => 'ENGINE=InnoDB default charset=utf8' }
116
+ end
117
+ end
118
+
119
+ private
120
+ def load_domains(domains, options)
121
+ if domains.empty? or domains.include?(:all)
122
+ require 'earth/all'
123
+ require 'earth/data_miner' if options[:apply_schemas] or options[:load_data_miner]
124
+ elsif !domains.include?(:none)
125
+ domains.each do |domain|
126
+ require "earth/#{domain}"
127
+ require "earth/#{domain}/data_miner" if options[:apply_schemas] or options[:load_data_miner]
128
+ end
129
+ end
130
+ end
131
+
132
+ def load_plugins
133
+ Dir[File.join(Earth.root, 'vendor', '**', 'init.rb')].each do |pluginit|
134
+ $:.unshift File.join(File.dirname(pluginit), 'lib')
135
+ load pluginit
136
+ end
137
+ end
138
+
139
+ def load_schemas
140
+ load_ar_schema
141
+ load_data_miner_schemas
142
+ end
143
+
144
+ def load_ar_schema
145
+ orig_std_out = STDOUT.clone
146
+ STDOUT.reopen File.open(File.join('/tmp', 'schema_output'), 'w')
147
+
148
+ load File.join(File.dirname(__FILE__), 'earth', 'schema.rb')
149
+ ensure
150
+ STDOUT.reopen(orig_std_out)
151
+ end
152
+
153
+ def load_data_miner_schemas
154
+ models = Module.constants.select do |k|
155
+ const = Object.const_get(k)
156
+ if const.instance_of?(Class)
157
+ const.superclass == ActiveRecord::Base
158
+ else
159
+ false
160
+ end
161
+ end
162
+ models.sort.each do |model|
163
+ klass = Object.const_get(model)
164
+ if klass.respond_to?(:execute_schema) and !klass.table_exists?
165
+ klass.execute_schema
166
+ end
167
+ end
168
+ end
169
+ end
data/lib/earth/air.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'earth/air/aircraft'
2
+ require 'earth/air/aircraft_class'
3
+ require 'earth/air/aircraft_manufacturer'
4
+ require 'earth/air/airline'
5
+ require 'earth/air/airport'
6
+ require 'earth/air/flight_configuration'
7
+ require 'earth/air/flight_distance_class'
8
+ require 'earth/air/flight_domesticity'
9
+ require 'earth/air/flight_fuel_type'
10
+ require 'earth/air/flight_propulsion'
11
+ require 'earth/air/flight_seat_class'
12
+ require 'earth/air/flight_segment'
13
+ require 'earth/air/flight_service'
@@ -0,0 +1,32 @@
1
+ class Aircraft < ActiveRecord::Base
2
+ set_primary_key :icao_code
3
+
4
+ belongs_to :aircraft_class, :foreign_key => 'brighter_planet_aircraft_class_code'
5
+ belongs_to :manufacturer, :foreign_key => 'manufacturer_name', :class_name => 'AircraftManufacturer'
6
+ has_many :segments, :foreign_key => 'bts_aircraft_type_code', :class_name => "FlightSegment", :primary_key => 'bts_aircraft_type_code'
7
+
8
+
9
+ falls_back_on :m3 => lambda {
10
+ weighted_average(:m3, :weighted_by => [:segments, :passengers])
11
+ }, # 9.73423082858437e-08 r7110: 8.6540464368905e-8 r6972: 8.37e-8
12
+ :m2 => lambda {
13
+ weighted_average(:m2, :weighted_by => [:segments, :passengers])
14
+ }, # -0.000134350543484608 r7110: -0.00015337661447817 r6972: -4.09e-5
15
+ :m1 => lambda {
16
+ weighted_average(:m1, :weighted_by => [:segments, :passengers])
17
+ }, # 6.7728101555467 r7110: 4.7781966869412 r6972: 7.85
18
+ :endpoint_fuel => lambda {
19
+ weighted_average(:endpoint_fuel, :weighted_by => [:segments, :passengers])
20
+ }, # 1527.81790006167 r7110: 1065.3476555284 r6972: 1.72e3
21
+ :seats => lambda {
22
+ weighted_average(:seats, :weighted_by => [:segments, :passengers])
23
+ } # 62.1741
24
+
25
+ data_miner do
26
+ tap "Brighter Planet's sanitized aircraft data", Earth.taps_server
27
+
28
+ process "pull dependencies" do
29
+ run_data_miner_on_belongs_to_associations
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,171 @@
1
+ Aircraft.class_eval do
2
+ class Aircraft::BtsMatcher
3
+ attr_reader :wants
4
+ def initialize(wants)
5
+ @wants = wants
6
+ end
7
+ def match(raw_faa_icao_record)
8
+ @_match ||= Hash.new
9
+ return @_match[raw_faa_icao_record] if @_match.has_key?(raw_faa_icao_record)
10
+ faa_icao_record = [ raw_faa_icao_record['Manufacturer'] + ' ' + raw_faa_icao_record['Model'] ]
11
+ bts_record = Aircraft.bts_name_dictionary.left_to_right faa_icao_record
12
+ retval = case wants
13
+ when :bts_aircraft_type_code
14
+ bts_record['Code']
15
+ when :bts_name
16
+ bts_record['Description']
17
+ end if bts_record
18
+ @_match[raw_faa_icao_record] = retval
19
+ end
20
+ end
21
+
22
+ class Aircraft::FuelUseMatcher
23
+ def match(raw_fuel_use_record)
24
+ @_match ||= Hash.new
25
+ return @_match[raw_fuel_use_record] if @_match.has_key?(raw_fuel_use_record)
26
+
27
+ aircraft_record = if raw_fuel_use_record['ICAO'] =~ /\A[0-9A-Z]+\z/
28
+ Aircraft.find_by_icao_code raw_fuel_use_record['ICAO']
29
+ end
30
+
31
+ aircraft_record ||= if raw_fuel_use_record['Aircraft Name'].present?
32
+ Aircraft.icao_name_dictionary.left_to_right [ raw_fuel_use_record['Aircraft Name'] ]
33
+ end
34
+
35
+ if aircraft_record
36
+ @_match[raw_fuel_use_record] = aircraft_record.icao_code
37
+ else
38
+ raise "Didn't find a match for #{raw_fuel_use_record['Aircraft Name']} (#{raw_fuel_use_record['ICAO']}), which we found in the fuel use spreadsheet"
39
+ end
40
+ end
41
+ end
42
+
43
+ class Aircraft::Guru
44
+ # for errata
45
+ def is_a_dc_plane?(row)
46
+ row['Designator'] =~ /^DC\d/i
47
+ end
48
+
49
+ # def is_a_crj_900?(row)
50
+ # row['Designator'].downcase == 'crj9'
51
+ # end
52
+
53
+ def is_a_g159?(row)
54
+ row['Designator'] =~ /^G159$/
55
+ end
56
+
57
+ def is_a_galx?(row)
58
+ row['Designator'] =~ /^GALX$/
59
+ end
60
+
61
+ def method_missing(method_id, *args, &block)
62
+ if method_id.to_s =~ /\Ais_n?o?t?_?attributed_to_([^\?]+)/
63
+ manufacturer_name = $1
64
+ manufacturer_regexp = Regexp.new(manufacturer_name.gsub('_', ' ?'), Regexp::IGNORECASE)
65
+ matches = manufacturer_regexp.match(args.first['Manufacturer']) # row['Manufacturer'] =~ /mcdonnell douglas/i
66
+ method_id.to_s.include?('not_attributed') ? matches.nil? : !matches.nil?
67
+ else
68
+ super
69
+ end
70
+ end
71
+ end
72
+
73
+ data_miner do
74
+ process "Don't re-import too often" do
75
+ raise DataMiner::Skip unless DataMiner::Run.allowed? Aircraft
76
+ end
77
+
78
+ schema Earth.database_options do
79
+ string 'icao_code'
80
+ string 'manufacturer_name'
81
+ string 'name'
82
+ string 'bts_name'
83
+ string 'bts_aircraft_type_code'
84
+ string 'brighter_planet_aircraft_class_code'
85
+ string 'fuel_use_aircraft_name'
86
+ float 'm3'
87
+ string 'm3_units'
88
+ float 'm2'
89
+ string 'm2_units'
90
+ float 'm1'
91
+ string 'm1_units'
92
+ float 'endpoint_fuel'
93
+ string 'endpoint_fuel_units'
94
+ float 'seats'
95
+ float 'distance'
96
+ string 'distance_units'
97
+ float 'load_factor'
98
+ float 'freight_share'
99
+ float 'payload'
100
+ float 'weighting'
101
+ index 'bts_aircraft_type_code'
102
+ end
103
+
104
+ ('A'..'Z').each do |letter|
105
+ # ('Z'..'Z').each do |letter|
106
+ import( "ICAO aircraft codes starting with the letter #{letter} used by the FAA",
107
+ :url => "http://www.faa.gov/air_traffic/publications/atpubs/CNT/5-2-#{letter}.htm",
108
+ :errata => Errata.new(:url => 'http://spreadsheets.google.com/pub?key=tObVAGyqOkCBtGid0tJUZrw',
109
+ :responder => Aircraft::Guru.new),
110
+ :encoding => 'windows-1252',
111
+ :row_xpath => '//table/tr[2]/td/table/tr',
112
+ :column_xpath => 'td' ) do
113
+ key 'icao_code', :field_name => 'Designator'
114
+ store 'bts_aircraft_type_code', :matcher => Aircraft::BtsMatcher.new(:bts_aircraft_type_code)
115
+ store 'bts_name', :matcher => Aircraft::BtsMatcher.new(:bts_name)
116
+ store 'manufacturer_name', :field_name => 'Manufacturer'
117
+ store 'name', :field_name => 'Model'
118
+ end
119
+ end
120
+
121
+ # TODO fixme need to remake aircraft classes dictionary based on ICAO codes
122
+ # sabshere 5/17/10 or maybe we can replace this with typ/weight class from FAA (?)
123
+ import "Brighter Planet's aircraft class codes",
124
+ :url => 'http://static.brighterplanet.com/science/data/transport/air/bts_aircraft_type/bts_aircraft_types-brighter_planet_aircraft_classes.csv' do
125
+ key 'bts_aircraft_type_code', :field_name => 'bts_aircraft_type'
126
+ store 'brighter_planet_aircraft_class_code'
127
+ end
128
+
129
+ # EEA
130
+ import "pre-calculated fuel use equation coefficients",
131
+ :url => 'http://static.brighterplanet.com/science/data/transport/air/fuel_use/aircraft_fuel_use_formulae.ods',
132
+ :select => lambda { |row| row['ICAO'].present? or row['Aircraft Name'].present? } do
133
+ key 'icao_code', :matcher => Aircraft::FuelUseMatcher.new
134
+ store 'fuel_use_aircraft_name', :field_name => 'Aircraft Name'
135
+ store 'm3'
136
+ store 'm2'
137
+ store 'm1'
138
+ store 'endpoint_fuel', :field_name => 'b'
139
+ end
140
+
141
+ process "Derive some average flight characteristics from flight segments" do
142
+ FlightSegment.run_data_miner!
143
+ aircraft = Aircraft.arel_table
144
+ segments = FlightSegment.arel_table
145
+
146
+ # non-working joins method
147
+ # update_all "aircraft.distance_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:distance, :weighted_by => :passengers ).to_sql}) AS anonymous_1)"
148
+ # update_all "aircraft.load_factor_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:load_factor, :weighted_by => :passengers ).to_sql}) AS anonymous_1)"
149
+ # execute %{
150
+ # update aircraft as t1
151
+ # set t1.distance_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:distance, :weighted_by => :passengers ).where('t1.bts_aircraft_type_code = flight_segments.bts_aircraft_type_code').to_sql}) AS anonymous_1)
152
+ # }
153
+
154
+ conditional_relation = aircraft[:bts_aircraft_type_code].eq(segments[:bts_aircraft_type_code])
155
+ update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
156
+ update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
157
+ update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
158
+ update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
159
+ update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).where(conditional_relation).to_sql})"
160
+
161
+ update_all "weighting = (#{segments.project(segments[:passengers].sum).where(aircraft[:bts_aircraft_type_code].eq(segments[:bts_aircraft_type_code])).to_sql})"
162
+ end
163
+
164
+ [ AircraftManufacturer ].each do |synthetic_resource|
165
+ process "Synthesize #{synthetic_resource}" do
166
+ synthetic_resource.run_data_miner!
167
+ end
168
+ end
169
+
170
+ end
171
+ end
@@ -0,0 +1,10 @@
1
+ class AircraftClass < ActiveRecord::Base
2
+ set_primary_key :brighter_planet_aircraft_class_code
3
+
4
+ has_many :aircraft, :foreign_key => 'brighter_planet_aircraft_class_code'
5
+ # has_many :airline_aircraft_seat_classes, :through => :aircraft
6
+
7
+ data_miner do
8
+ tap "Brighter Planet's aircraft class data", Earth.taps_server
9
+ end
10
+ end
@@ -0,0 +1,42 @@
1
+ AircraftClass.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'brighter_planet_aircraft_class_code'
5
+ string 'name'
6
+ float 'm1'
7
+ float 'm2'
8
+ float 'm3'
9
+ float 'endpoint_fuel'
10
+ integer 'seats'
11
+ end
12
+
13
+ import "Brighter Planet's aircraft classes", :url => 'http://static.brighterplanet.com/science/data/transport/air/brighter_planet_aircraft_classes.csv' do
14
+ key 'brighter_planet_aircraft_class_code'
15
+ store 'name', :field_name => 'description'
16
+ end
17
+
18
+ process "Derive some average aircraft chraracteristics from aircraft" do
19
+ Aircraft.run_data_miner!
20
+ aircraft = Aircraft.arel_table
21
+ aircraft_classes = AircraftClass.arel_table
22
+ conditional_relation = aircraft_classes[:brighter_planet_aircraft_class_code].eq(aircraft[:brighter_planet_aircraft_class_code])
23
+ %w{ m1 m2 m3 endpoint_fuel }.each do |column|
24
+ relation = Aircraft.weighted_average_relation(column).
25
+ where(conditional_relation)
26
+ update_all "#{column} = (#{relation.to_sql})"
27
+ end
28
+ end
29
+
30
+ process "Derive some average aircraft characteristics from flight segments" do # FIXME TODO why not derive this from aircraft?
31
+ FlightSegment.run_data_miner!
32
+ aircraft = Aircraft.arel_table
33
+ aircraft_classes = AircraftClass.arel_table
34
+ segments = FlightSegment.arel_table
35
+ relation = FlightSegment.joins(:aircraft). # this requires associations
36
+ weighted_average_relation(:seats, :weighted_by => :passengers).
37
+ where(aircraft_classes[:brighter_planet_aircraft_class_code].eq(aircraft[:brighter_planet_aircraft_class_code]))
38
+ update_all "seats = (#{relation.to_sql})"
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,9 @@
1
+ class AircraftManufacturer < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :aircraft, :foreign_key => 'manufacturer_name'
5
+
6
+ data_miner do
7
+ tap "Brighter Planet's aircraft manufacturer data", Earth.taps_server
8
+ end
9
+ end