earth 0.6.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/earth.gemspec +1 -1
  2. data/lib/earth/air/flight_distance_class.rb +1 -1
  3. data/lib/earth/air/flight_distance_class/data_miner.rb +3 -2
  4. data/lib/earth/air/flight_seat_class/data_miner.rb +4 -29
  5. data/lib/earth/air/flight_segment.rb +4 -0
  6. data/lib/earth/automobile.rb +1 -0
  7. data/lib/earth/automobile/automobile_fuel/data_miner.rb +3 -3
  8. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +1 -1
  9. data/lib/earth/locality.rb +3 -0
  10. data/lib/earth/locality/country.rb +32 -9
  11. data/lib/earth/locality/country/data_miner.rb +38 -2
  12. data/lib/earth/locality/country_rail_class.rb +18 -0
  13. data/lib/earth/locality/country_rail_class/data_miner.rb +16 -0
  14. data/lib/earth/locality/country_rail_traction.rb +13 -0
  15. data/lib/earth/locality/country_rail_traction/data_miner.rb +34 -0
  16. data/lib/earth/locality/country_rail_traction_class.rb +14 -0
  17. data/lib/earth/locality/country_rail_traction_class/data_miner.rb +35 -0
  18. data/lib/earth/locality/data_miner.rb +3 -0
  19. data/lib/earth/locality/zip_code.rb +9 -7
  20. data/lib/earth/rail.rb +8 -0
  21. data/lib/earth/rail/data_miner.rb +9 -0
  22. data/lib/earth/rail/national_transit_database_company.rb +37 -0
  23. data/lib/earth/rail/national_transit_database_company/data_miner.rb +12 -0
  24. data/lib/earth/rail/national_transit_database_mode.rb +12 -0
  25. data/lib/earth/rail/national_transit_database_mode/data_miner.rb +10 -0
  26. data/lib/earth/rail/national_transit_database_record.rb +41 -0
  27. data/lib/earth/rail/national_transit_database_record/data_miner.rb +57 -0
  28. data/lib/earth/rail/rail_class.rb +2 -63
  29. data/lib/earth/rail/rail_class/data_miner.rb +13 -12
  30. data/lib/earth/rail/rail_company.rb +26 -0
  31. data/lib/earth/rail/rail_company/data_miner.rb +98 -0
  32. data/lib/earth/rail/rail_company_traction.rb +12 -0
  33. data/lib/earth/rail/rail_company_traction/data_miner.rb +4 -0
  34. data/lib/earth/rail/rail_company_traction_class.rb +14 -0
  35. data/lib/earth/rail/rail_company_traction_class/data_miner.rb +4 -0
  36. data/lib/earth/rail/rail_fuel.rb +18 -0
  37. data/lib/earth/rail/rail_fuel/data_miner.rb +36 -0
  38. data/lib/earth/rail/rail_traction.rb +5 -0
  39. data/lib/earth/rail/rail_traction/data_miner.rb +21 -0
  40. data/lib/earth/version.rb +1 -1
  41. data/spec/earth_spec.rb +14 -2
  42. metadata +46 -30
@@ -1 +1,10 @@
1
1
  require 'earth/rail/rail_class/data_miner'
2
+ require 'earth/rail/rail_company/data_miner'
3
+ require 'earth/rail/rail_company_traction/data_miner'
4
+ require 'earth/rail/rail_company_traction_class/data_miner'
5
+ require 'earth/rail/rail_class/data_miner'
6
+ require 'earth/rail/rail_fuel/data_miner'
7
+ require 'earth/rail/rail_traction/data_miner'
8
+ require 'earth/rail/national_transit_database_company/data_miner'
9
+ require 'earth/rail/national_transit_database_mode/data_miner'
10
+ require 'earth/rail/national_transit_database_record/data_miner'
@@ -0,0 +1,37 @@
1
+ class NationalTransitDatabaseCompany < ActiveRecord::Base
2
+ set_primary_key :id
3
+ set_table_name :ntd_companies
4
+
5
+ has_many :ntd_records, :foreign_key => 'company_id', :primary_key => 'id', :class_name => 'NationalTransitDatabaseRecord'
6
+
7
+ def self.rail_companies
8
+ NationalTransitDatabaseRecord.rail_records.map(&:ntd_company).uniq
9
+ end
10
+
11
+ def rail_records
12
+ ntd_records.where(:mode_code => NationalTransitDatabaseMode.rail_modes)
13
+ end
14
+
15
+ # Methods to calculate summary statistics from rail_records
16
+ [:rail_passengers, :rail_passenger_distance, :rail_vehicle_distance, :rail_vehicle_time, :rail_electricity, :rail_diesel].each do |method|
17
+ define_method method do
18
+ attribute = method.to_s.split('rail_')[1].to_sym
19
+ rail_records.sum(attribute) > 0 ? rail_records.sum(attribute) : nil
20
+ end
21
+ end
22
+
23
+ # Methods to look up units from from rail_records
24
+ [:rail_passenger_distance_units, :rail_vehicle_distance_units, :rail_vehicle_time_units, :rail_electricity_units, :rail_diesel_units].each do |method|
25
+ define_method method do
26
+ attribute = method.to_s.split('rail_')[1].to_sym
27
+ units = rail_records.map(&attribute).uniq
28
+ (units.count == 1 and units[0].present?) ? units[0] : raise("Error: units missing or multiple units in #{name}'s NTD records")
29
+ end
30
+ end
31
+
32
+ col :id
33
+ col :name
34
+ col :acronym
35
+ col :zip_code_name
36
+ col :duns_number
37
+ end
@@ -0,0 +1,12 @@
1
+ NationalTransitDatabaseCompany.class_eval do
2
+ data_miner do
3
+ import "US transit companies from the National Transit Database",
4
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdHBTZC1GUzg5VEU4QW9NOUo3V1BJWUE&output=csv' do
5
+ key 'id', :field_name => 'trs_id'
6
+ store 'name', :nullify => true
7
+ store 'acronym', :nullify => true
8
+ store 'zip_code_name', :nullify => true
9
+ store 'duns_number', :nullify => true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class NationalTransitDatabaseMode < ActiveRecord::Base
2
+ set_primary_key :code
3
+ set_table_name :ntd_modes
4
+
5
+ def self.rail_modes
6
+ where(:rail_mode => true)
7
+ end
8
+
9
+ col :code
10
+ col :name
11
+ col :rail_mode, :type => :boolean
12
+ end
@@ -0,0 +1,10 @@
1
+ NationalTransitDatabaseMode.class_eval do
2
+ data_miner do
3
+ import "National Transit Database modes",
4
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdGFTLVpMdFgwSTQzTTFuc2lIVUdfSHc&output=csv' do
5
+ key 'code'
6
+ store 'name', :nullify => true
7
+ store 'rail_mode', :nullify => true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ class NationalTransitDatabaseRecord < ActiveRecord::Base
2
+ set_primary_key :name
3
+ set_table_name :ntd_records
4
+
5
+ belongs_to :ntd_company, :foreign_key => 'company_id', :class_name => 'NationalTransitDatabaseCompany'
6
+
7
+ def self.rail_records
8
+ where(:mode_code => NationalTransitDatabaseMode.rail_modes)
9
+ end
10
+
11
+ col :name
12
+ col :company_id
13
+ col :mode_code
14
+ col :service_type
15
+ col :vehicle_distance, :type => :float
16
+ col :vehicle_distance_units
17
+ col :vehicle_time, :type => :float
18
+ col :vehicle_time_units
19
+ col :passenger_distance, :type => :float
20
+ col :passenger_distance_units
21
+ col :passengers, :type => :float
22
+ col :electricity, :type => :float
23
+ col :electricity_units
24
+ col :diesel, :type => :float
25
+ col :diesel_units
26
+ col :gasoline, :type => :float
27
+ col :gasoline_units
28
+ col :lpg, :type => :float
29
+ col :lpg_units
30
+ col :lng, :type => :float
31
+ col :lng_units
32
+ col :cng, :type => :float
33
+ col :cng_units
34
+ col :kerosene, :type => :float
35
+ col :kerosene_units
36
+ col :biodiesel, :type => :float
37
+ col :biodiesel_units
38
+ col :other_fuel, :type => :float
39
+ col :other_fuel_units
40
+ col :other_fuel_description
41
+ end
@@ -0,0 +1,57 @@
1
+ NationalTransitDatabaseRecord.class_eval do
2
+ data_miner do
3
+ import "US National Transit Database service data",
4
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdF9Hbktvc3BMNDRWZHhDRU9uMVZfWVE&output=csv' do
5
+ key 'name', :synthesize => lambda { |row| [row['trs_id'], row['mode_code'], row['service_code']].join(' ') }
6
+ store 'company_id', :field_name => 'trs_id'
7
+ store 'mode_code'
8
+ store 'service_type', :field_name => 'service_code', :dictionary => { :input => 'code', :output => 'name', :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDBTZENxb3A1SzJaNTVEVGZ5cTdaMVE&output=csv' }
9
+ store 'vehicle_distance', :field_name => 'vehicle_or_train_revenue_miles', :units => 'miles'
10
+ store 'vehicle_time', :field_name => 'vehicle_or_train_revenue_hours', :units => 'hours'
11
+ store 'passenger_distance', :field_name => 'passenger_miles', :units => 'miles'
12
+ store 'passengers'
13
+ end
14
+
15
+ import "US National Transit Database fuel consumption data",
16
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDItVVR5NjA2Y3FCVjgza25Ccy0zS2c&output=csv' do
17
+ key 'name', :synthesize => lambda { |row| [row['trs_id'], row['mode_code'], row['service_code']].join(' ') }
18
+ store 'company_id', :field_name => 'trs_id'
19
+ store 'mode_code'
20
+ store 'service_type', :field_name => 'service_code', :dictionary => { :input => 'code', :output => 'name', :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDBTZENxb3A1SzJaNTVEVGZ5cTdaMVE&output=csv' }
21
+ store 'electricity', :synthesize => lambda { |row| row['electricity_kwh'].to_f + row['battery_kwh'].to_f }, :units => 'kilowatt_hours', :nullify => true
22
+ store 'diesel', :field_name => 'diesel_gallons', :units => 'gallons', :nullify => true
23
+ store 'gasoline', :field_name => 'gasoline_gallons', :units => 'gallons', :nullify => true
24
+ store 'lpg', :field_name => 'lpg_gallons', :units => 'gallons', :nullify => true
25
+ store 'lng', :field_name => 'lng_gallons', :units => 'gallons', :nullify => true
26
+ store 'cng', :field_name => 'cng_gallons', :units => 'gallons', :nullify => true
27
+ store 'kerosene', :field_name => 'kerosene_gallons', :units => 'gallons', :nullify => true
28
+ store 'biodiesel', :field_name => 'biodiesel_gallons', :units => 'gallons', :nullify => true
29
+ store 'other_fuel', :nullify => true
30
+ store 'other_fuel_description', :field_name => 'other_fuel_description', :nullify => true
31
+ end
32
+
33
+ process "Convert miles to kilometres" do
34
+ conversion_factor = 1.miles.to(:kilometres)
35
+ %{ vehicle_distance passenger_distance }.split.each do |field|
36
+ connection.execute %{
37
+ UPDATE #{table_name}
38
+ SET #{field} = #{field} * #{conversion_factor},
39
+ #{field}_units = 'kilometres'
40
+ WHERE #{field}_units = 'miles'
41
+ }
42
+ end
43
+ end
44
+
45
+ process "Convert gallons to litres" do
46
+ conversion_factor = 1.gallons.to(:litres)
47
+ %{ diesel gasoline lpg lng cng kerosene biodiesel }.split.each do |fuel|
48
+ connection.execute %{
49
+ UPDATE #{table_name}
50
+ SET #{fuel} = #{fuel} * #{conversion_factor},
51
+ #{fuel}_units = 'litres'
52
+ WHERE #{fuel}_units = 'gallons'
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,66 +1,5 @@
1
1
  class RailClass < ActiveRecord::Base
2
2
  set_primary_key :name
3
- col :name
4
- col :description
5
- col :passengers, :type => :float
6
- col :distance, :type => :float
7
- col :distance_units
8
- col :speed, :type => :float
9
- col :speed_units
10
- col :electricity_intensity, :type => :float
11
- col :electricity_intensity_units
12
- col :diesel_intensity, :type => :float
13
- col :diesel_intensity_units
14
-
15
- # verify "Passengers, distance, speed, and electricity intensity should be greater than zero" do
16
- # RailClass.all.each do |rail_class|
17
- # %w{ passengers distance speed electricity_intensity }.each do |attribute|
18
- # value = rail_class.send(:"#{attribute}")
19
- # unless value > 0
20
- # raise "Invalid #{attribute} for RailClass #{rail_class.name}: #{value} (should be > 0)"
21
- # end
22
- # end
23
- # end
24
- # end
25
- #
26
- # verify "Distance units should be kilometres" do
27
- # RailClass.all.each do |rail_class|
28
- # unless rail_class.distance_units == "kilometres"
29
- # raise "Invalid distance units for RailClass #{rail_class.name}: #{rail_class.distance_units} (should be kilometres)"
30
- # end
31
- # end
32
- # end
33
- #
34
- # verify "Speed units should be kilometres per hour" do
35
- # RailClass.all.each do |rail_class|
36
- # unless rail_class.speed_units == "kilometres_per_hour"
37
- # raise "Invalid speed units for RailClass #{rail_class.name}: #{rail_class.speed_units} (should be kilometres_per_hour)"
38
- # end
39
- # end
40
- # end
41
- #
42
- # verify "Electricity intensity units should be kilowatt hours per kilometre" do
43
- # RailClass.all.each do |rail_class|
44
- # unless rail_class.electricity_intensity_units == "kilowatt_hours_per_kilometre"
45
- # raise "Invalid electricity intensity units for RailClass #{rail_class.name}: #{rail_class.electricity_intensity_units} (should be kilowatt_hours_per_kilometre)"
46
- # end
47
- # end
48
- # end
49
- #
50
- # verify "Diesel intensity should be zero or more" do
51
- # RailClass.all.each do |rail_class|
52
- # unless rail_class.diesel_intensity >= 0
53
- # raise "Invalid diesel intensity for RailClass #{rail_class.name}: #{rail_class.diesel_intensity} (should be > 0)"
54
- # end
55
- # end
56
- # end
57
- #
58
- # verify "Diesel intensity units should be litres per kilometre" do
59
- # RailClass.all.each do |rail_class|
60
- # unless rail_class.diesel_intensity_units == "litres_per_kilometre"
61
- # raise "Invalid distance units for RailClass #{rail_class.name}: #{rail_class.diesel_intensity_units} (should be litres_per_kilometre)"
62
- # end
63
- # end
64
- # end
65
3
 
66
- end
4
+ col :name
5
+ end
@@ -1,18 +1,19 @@
1
1
  RailClass.class_eval do
2
2
  data_miner do
3
- process "Define some unit conversions" do
4
- Conversions.register :gallons_per_mile, :litres_per_kilometre, 2.35214583
3
+ process "Ensure CountryRailClass, CountryRailTractionClass, and RailCompanyTractionClass are populated" do
4
+ CountryRailTractionClass.run_data_miner!
5
+ CountryRailClass.run_data_miner!
6
+ RailCompanyTractionClass.run_data_miner!
5
7
  end
6
-
7
- import "a list of rail classes and pre-calculated trip and fuel use characteristics",
8
- :url => 'https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdHRYaDNvRXMtZGoxNmRiOHlNWGV6b2c&hl=en&gid=0&output=csv' do
9
- key 'name'
10
- store 'description'
11
- store 'passengers'
12
- store 'distance', :units_field_name => 'distance_units'
13
- store 'speed', :units_field_name => 'speed_units'
14
- store 'electricity_intensity', :units_field_name => 'electricity_intensity_units'
15
- store 'diesel_intensity', :units_field_name => 'diesel_intensity_units'
8
+
9
+ process "Derive rail class names from CountryRailClass, CountryRailTractionClass, and RailCompanyTractionClass" do
10
+ names = []
11
+ names += CountryRailTractionClass.select("DISTINCT rail_class_name").map(&:rail_class_name)
12
+ names += CountryRailClass.select("DISTINCT rail_class_name").map(&:rail_class_name)
13
+ names += RailCompanyTractionClass.select("DISTINCT rail_class_name").map(&:rail_class_name)
14
+ names.uniq.each do |name|
15
+ RailClass.find_or_create_by_name(name)
16
+ end
16
17
  end
17
18
  end
18
19
  end
@@ -0,0 +1,26 @@
1
+ class RailCompany < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ belongs_to :country, :foreign_key => 'country_iso_3166_code'
5
+
6
+ col :name
7
+ col :country_iso_3166_code
8
+ col :duns_number
9
+ col :passengers, :type => :float
10
+ col :passenger_distance, :type => :float
11
+ col :passenger_distance_units
12
+ col :trip_distance, :type => :float
13
+ col :trip_distance_units
14
+ col :train_distance, :type => :float
15
+ col :train_distance_units
16
+ col :train_time, :type => :float
17
+ col :train_time_units
18
+ col :speed, :type => :float
19
+ col :speed_units
20
+ col :electricity_intensity, :type => :float
21
+ col :electricity_intensity_units
22
+ col :diesel_intensity, :type => :float
23
+ col :diesel_intensity_units
24
+ col :co2_emission_factor, :type => :float
25
+ col :co2_emission_factor_units
26
+ end
@@ -0,0 +1,98 @@
1
+ RailCompany.class_eval do
2
+ data_miner do
3
+ import "european rail company data from the UIC",
4
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDRpVkd3T0p1RDY4RzUzc0VUUVEwYmc&output=csv' do
5
+ key 'name'
6
+ store 'country_iso_3166_code'
7
+ store 'passengers', :nullify => true
8
+ store 'passenger_distance', :nullify => true, :units_field_name => 'passenger_distance_units'
9
+ store 'train_distance', :nullify => true, :units_field_name => 'train_distance_units'
10
+ end
11
+
12
+ import "Amtrak data",
13
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdGZ3UDdJT1NETUtELWVTLUR4R3RZbEE&output=csv' do
14
+ key 'name'
15
+ store 'country_iso_3166_code'
16
+ store 'passengers', :nullify => true
17
+ store 'passenger_distance', :nullify => true, :units_field_name => 'passenger_distance_units'
18
+ store 'train_distance', :nullify => true, :units_field_name => 'train_distance_units'
19
+ store 'train_time', :nullify => true, :units_field_name => 'train_time_units'
20
+ store 'electricity_intensity', :nullify => true, :units_field_name => 'electricity_intensity_units'
21
+ store 'diesel_intensity', :nullify => true, :units_field_name => 'diesel_intensity_units'
22
+ end
23
+
24
+ process "Ensure the National Transit Database data is imported" do
25
+ NationalTransitDatabaseRecord.run_data_miner!
26
+ NationalTransitDatabaseCompany.run_data_miner!
27
+ NationalTransitDatabaseMode.run_data_miner!
28
+ end
29
+
30
+ process "Derive US transit rail company data from the National Transit Database" do
31
+ NationalTransitDatabaseCompany.rail_companies.each do |ntd_company|
32
+ company = RailCompany.find_or_create_by_name(ntd_company.name)
33
+ company.country_iso_3166_code = 'US'
34
+ company.duns_number = ntd_company.duns_number
35
+ company.passengers = ntd_company.rail_passengers
36
+ company.passenger_distance = ntd_company.rail_passenger_distance
37
+ company.passenger_distance_units = ntd_company.rail_passenger_distance_units
38
+ company.train_distance = ntd_company.rail_vehicle_distance
39
+ company.train_distance_units = ntd_company.rail_vehicle_distance_units
40
+ company.train_time = ntd_company.rail_vehicle_time
41
+ company.train_time_units = ntd_company.rail_vehicle_time_units
42
+
43
+ if ntd_company.rail_electricity.present? and ntd_company.rail_electricity > 0 and ntd_company.rail_passenger_distance > 0
44
+ company.electricity_intensity = ntd_company.rail_electricity / ntd_company.rail_passenger_distance
45
+ company.electricity_intensity_units = "#{ntd_company.rail_electricity_units}_per_passenger_#{ntd_company.rail_passenger_distance_units.singularize}"
46
+ end
47
+
48
+ if ntd_company.rail_diesel.present? and ntd_company.rail_diesel > 0 and ntd_company.rail_passenger_distance > 0
49
+ company.diesel_intensity = ntd_company.rail_diesel / ntd_company.rail_passenger_distance
50
+ company.diesel_intensity_units = "#{ntd_company.rail_diesel_units}_per_passenger_#{ntd_company.rail_passenger_distance_units.singularize}"
51
+ end
52
+
53
+ company.save!
54
+ end
55
+ end
56
+
57
+ process "Calculate average trip distance" do
58
+ RailCompany.find_each do |company|
59
+ if company.passenger_distance.present? and company.passengers.present? and company.passengers > 0
60
+ company.trip_distance = company.passenger_distance / company.passengers
61
+ company.trip_distance_units = company.passenger_distance_units
62
+ company.save!
63
+ end
64
+ end
65
+ end
66
+
67
+ process "Calculate average trip speed" do
68
+ RailCompany.find_each do |company|
69
+ if company.train_distance.present? and company.train_time.present? and company.train_time > 0
70
+ company.speed = company.train_distance / company.train_time
71
+ company.speed_units = "#{company.train_distance_units}_per_#{company.train_time_units.singularize}"
72
+ company.save!
73
+ end
74
+ end
75
+ end
76
+
77
+ process "Ensure RailFuel is populated" do
78
+ RailFuel.run_data_miner!
79
+ end
80
+
81
+ process "Calculate co2 emission factor for US rail companies" do
82
+ RailCompany.where(:country_iso_3166_code => 'US').find_each do |company|
83
+ company.co2_emission_factor = 0
84
+
85
+ if company.diesel_intensity.present?
86
+ company.co2_emission_factor += company.diesel_intensity * RailFuel.find_by_name("diesel").co2_emission_factor
87
+ end
88
+
89
+ if company.electricity_intensity.present?
90
+ company.co2_emission_factor += company.electricity_intensity * (EgridSubregion.fallback.electricity_co2_emission_factor / (1 - EgridRegion.fallback.loss_factor))
91
+ end
92
+
93
+ company.co2_emission_factor_units = 'kilograms_per_passenger_kilometre'
94
+ company.save!
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,12 @@
1
+ class RailCompanyTraction < ActiveRecord::Base
2
+ set_primary_key :name
3
+ col :name
4
+ col :rail_company_name
5
+ col :rail_traction_name
6
+ col :electricity_intensity, :type => :float
7
+ col :electricity_intensity_units
8
+ col :diesel_intensity, :type => :float
9
+ col :diesel_intensity_units
10
+ col :co2_emission_factor, :type => :float
11
+ col :co2_emission_factor_units
12
+ end
@@ -0,0 +1,4 @@
1
+ RailCompanyTraction.class_eval do
2
+ data_miner do
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ class RailCompanyTractionClass < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ col :name
5
+ col :rail_company_name
6
+ col :rail_traction_name
7
+ col :rail_class_name
8
+ col :electricity_intensity, :type => :float
9
+ col :electricity_intensity_units
10
+ col :diesel_intensity, :type => :float
11
+ col :diesel_intensity_units
12
+ col :co2_emission_factor, :type => :float
13
+ col :co2_emission_factor_units
14
+ end