earth-ruby19 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +5 -0
- data/Gemfile.lock +138 -0
- data/LICENSE +20 -0
- data/README.markdown +38 -0
- data/lib/earth.rb +146 -0
- data/lib/earth/active_record_ext.rb +9 -0
- data/lib/earth/air.rb +13 -0
- data/lib/earth/air/aircraft.rb +21 -0
- data/lib/earth/air/aircraft/data_miner.rb +184 -0
- data/lib/earth/air/aircraft_class.rb +10 -0
- data/lib/earth/air/aircraft_class/data_miner.rb +42 -0
- data/lib/earth/air/aircraft_manufacturer.rb +9 -0
- data/lib/earth/air/aircraft_manufacturer/data_miner.rb +20 -0
- data/lib/earth/air/airline.rb +16 -0
- data/lib/earth/air/airline/data_miner.rb +57 -0
- data/lib/earth/air/airport.rb +44 -0
- data/lib/earth/air/airport/data_miner.rb +80 -0
- data/lib/earth/air/data_miner.rb +15 -0
- data/lib/earth/air/flight_configuration.rb +7 -0
- data/lib/earth/air/flight_configuration/data_miner.rb +16 -0
- data/lib/earth/air/flight_distance_class.rb +7 -0
- data/lib/earth/air/flight_distance_class/data_miner.rb +16 -0
- data/lib/earth/air/flight_domesticity.rb +6 -0
- data/lib/earth/air/flight_domesticity/data_miner.rb +57 -0
- data/lib/earth/air/flight_fuel_type.rb +12 -0
- data/lib/earth/air/flight_fuel_type/data_miner.rb +12 -0
- data/lib/earth/air/flight_propulsion.rb +7 -0
- data/lib/earth/air/flight_propulsion/data_miner.rb +16 -0
- data/lib/earth/air/flight_seat_class.rb +12 -0
- data/lib/earth/air/flight_seat_class/data_miner.rb +36 -0
- data/lib/earth/air/flight_segment.rb +29 -0
- data/lib/earth/air/flight_segment/data_miner.rb +330 -0
- data/lib/earth/air/flight_service.rb +7 -0
- data/lib/earth/air/flight_service/data_miner.rb +16 -0
- data/lib/earth/all.rb +11 -0
- data/lib/earth/automobile.rb +8 -0
- data/lib/earth/automobile/automobile_fuel_type.rb +18 -0
- data/lib/earth/automobile/automobile_fuel_type/data_miner.rb +45 -0
- data/lib/earth/automobile/automobile_make.rb +14 -0
- data/lib/earth/automobile/automobile_make/data_miner.rb +68 -0
- data/lib/earth/automobile/automobile_make_fleet_year.rb +15 -0
- data/lib/earth/automobile/automobile_make_fleet_year/data_miner.rb +29 -0
- data/lib/earth/automobile/automobile_make_year.rb +14 -0
- data/lib/earth/automobile/automobile_make_year/data_miner.rb +45 -0
- data/lib/earth/automobile/automobile_model.rb +14 -0
- data/lib/earth/automobile/automobile_model/data_miner.rb +38 -0
- data/lib/earth/automobile/automobile_model_year.rb +15 -0
- data/lib/earth/automobile/automobile_model_year/data_miner.rb +51 -0
- data/lib/earth/automobile/automobile_size_class.rb +14 -0
- data/lib/earth/automobile/automobile_size_class/data_miner.rb +43 -0
- data/lib/earth/automobile/automobile_variant.rb +17 -0
- data/lib/earth/automobile/automobile_variant/data_miner.rb +460 -0
- data/lib/earth/automobile/data_miner.rb +8 -0
- data/lib/earth/base.rb +7 -0
- data/lib/earth/bus.rb +1 -0
- data/lib/earth/bus/bus_class.rb +19 -0
- data/lib/earth/bus/bus_class/data_miner.rb +41 -0
- data/lib/earth/bus/data_miner.rb +1 -0
- data/lib/earth/conversions_ext.rb +45 -0
- data/lib/earth/data_miner.rb +10 -0
- data/lib/earth/diet.rb +2 -0
- data/lib/earth/diet/data_miner.rb +2 -0
- data/lib/earth/diet/diet_class.rb +15 -0
- data/lib/earth/diet/diet_class/data_miner.rb +36 -0
- data/lib/earth/diet/food_group.rb +17 -0
- data/lib/earth/diet/food_group/data_miner.rb +26 -0
- data/lib/earth/fuel.rb +2 -0
- data/lib/earth/fuel/data_miner.rb +2 -0
- data/lib/earth/fuel/fuel_price.rb +13 -0
- data/lib/earth/fuel/fuel_price/data_miner.rb +20 -0
- data/lib/earth/fuel/fuel_type.rb +18 -0
- data/lib/earth/fuel/fuel_type/data_miner.rb +37 -0
- data/lib/earth/hospitality.rb +1 -0
- data/lib/earth/hospitality/data_miner.rb +1 -0
- data/lib/earth/hospitality/lodging_class.rb +9 -0
- data/lib/earth/hospitality/lodging_class/data_miner.rb +30 -0
- data/lib/earth/industry.rb +10 -0
- data/lib/earth/industry/industry.rb +23 -0
- data/lib/earth/industry/industry_product.rb +22 -0
- data/lib/earth/industry/industry_product_line.rb +20 -0
- data/lib/earth/industry/industry_sector.rb +20 -0
- data/lib/earth/industry/merchant.rb +18 -0
- data/lib/earth/industry/merchant_category.rb +22 -0
- data/lib/earth/industry/merchant_category_industry.rb +20 -0
- data/lib/earth/industry/product_line.rb +22 -0
- data/lib/earth/industry/product_line_industry_product.rb +20 -0
- data/lib/earth/industry/sector.rb +19 -0
- data/lib/earth/inflectors.rb +9 -0
- data/lib/earth/locality.rb +10 -0
- data/lib/earth/locality/census_division.rb +22 -0
- data/lib/earth/locality/census_division/data_miner.rb +64 -0
- data/lib/earth/locality/census_region.rb +13 -0
- data/lib/earth/locality/census_region/data_miner.rb +17 -0
- data/lib/earth/locality/climate_division.rb +17 -0
- data/lib/earth/locality/climate_division/data_miner.rb +20 -0
- data/lib/earth/locality/country.rb +13 -0
- data/lib/earth/locality/country/data_miner.rb +19 -0
- data/lib/earth/locality/data_miner.rb +10 -0
- data/lib/earth/locality/egrid_region.rb +15 -0
- data/lib/earth/locality/egrid_region/data_miner.rb +35 -0
- data/lib/earth/locality/egrid_subregion.rb +16 -0
- data/lib/earth/locality/egrid_subregion/data_miner.rb +65 -0
- data/lib/earth/locality/petroleum_administration_for_defense_district.rb +13 -0
- data/lib/earth/locality/petroleum_administration_for_defense_district/data_miner.rb +21 -0
- data/lib/earth/locality/state.rb +22 -0
- data/lib/earth/locality/state/data_miner.rb +37 -0
- data/lib/earth/locality/urbanity.rb +10 -0
- data/lib/earth/locality/urbanity/data_miner.rb +15 -0
- data/lib/earth/locality/zip_code.rb +23 -0
- data/lib/earth/locality/zip_code/data_miner.rb +43 -0
- data/lib/earth/pet.rb +4 -0
- data/lib/earth/pet/breed.rb +15 -0
- data/lib/earth/pet/breed/data_miner.rb +25 -0
- data/lib/earth/pet/breed_gender.rb +14 -0
- data/lib/earth/pet/breed_gender/data_miner.rb +21 -0
- data/lib/earth/pet/data_miner.rb +4 -0
- data/lib/earth/pet/gender.rb +10 -0
- data/lib/earth/pet/gender/data_miner.rb +13 -0
- data/lib/earth/pet/species.rb +40 -0
- data/lib/earth/pet/species/data_miner.rb +42 -0
- data/lib/earth/rail.rb +1 -0
- data/lib/earth/rail/data_miner.rb +1 -0
- data/lib/earth/rail/rail_class.rb +16 -0
- data/lib/earth/rail/rail_class/data_miner.rb +36 -0
- data/lib/earth/residence.rb +8 -0
- data/lib/earth/residence/air_conditioner_use.rb +13 -0
- data/lib/earth/residence/air_conditioner_use/data_miner.rb +22 -0
- data/lib/earth/residence/clothes_machine_use.rb +10 -0
- data/lib/earth/residence/clothes_machine_use/data_miner.rb +28 -0
- data/lib/earth/residence/data_miner.rb +8 -0
- data/lib/earth/residence/dishwasher_use.rb +10 -0
- data/lib/earth/residence/dishwasher_use/data_miner.rb +28 -0
- data/lib/earth/residence/residence_appliance.rb +16 -0
- data/lib/earth/residence/residence_appliance/data_miner.rb +20 -0
- data/lib/earth/residence/residence_class.rb +16 -0
- data/lib/earth/residence/residence_class/data_miner.rb +15 -0
- data/lib/earth/residence/residence_fuel_price.rb +18 -0
- data/lib/earth/residence/residence_fuel_price/data_miner.rb +200 -0
- data/lib/earth/residence/residence_fuel_type.rb +32 -0
- data/lib/earth/residence/residence_fuel_type/data_miner.rb +18 -0
- data/lib/earth/residence/residential_energy_consumption_survey_response.rb +39 -0
- data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +283 -0
- data/spec/lib/earth_spec.rb +25 -0
- data/spec/spec_helper.rb +11 -0
- data/vendor/geokit-rails/CHANGELOG.rdoc +46 -0
- data/vendor/geokit-rails/MIT-LICENSE +20 -0
- data/vendor/geokit-rails/README.markdown +561 -0
- data/vendor/geokit-rails/Rakefile +18 -0
- data/vendor/geokit-rails/about.yml +9 -0
- data/vendor/geokit-rails/assets/api_keys_template +61 -0
- data/vendor/geokit-rails/init.rb +1 -0
- data/vendor/geokit-rails/install.rb +14 -0
- data/vendor/geokit-rails/lib/geokit-rails.rb +24 -0
- data/vendor/geokit-rails/lib/geokit-rails/acts_as_mappable.rb +456 -0
- data/vendor/geokit-rails/lib/geokit-rails/adapters/abstract.rb +31 -0
- data/vendor/geokit-rails/lib/geokit-rails/adapters/mysql.rb +22 -0
- data/vendor/geokit-rails/lib/geokit-rails/adapters/postgresql.rb +22 -0
- data/vendor/geokit-rails/lib/geokit-rails/adapters/sqlserver.rb +43 -0
- data/vendor/geokit-rails/lib/geokit-rails/defaults.rb +22 -0
- data/vendor/geokit-rails/lib/geokit-rails/geocoder_control.rb +16 -0
- data/vendor/geokit-rails/lib/geokit-rails/ip_geocode_lookup.rb +46 -0
- data/vendor/geokit-rails/test/acts_as_mappable_test.rb +474 -0
- data/vendor/geokit-rails/test/boot.rb +25 -0
- data/vendor/geokit-rails/test/database.yml +20 -0
- data/vendor/geokit-rails/test/fixtures/companies.yml +7 -0
- data/vendor/geokit-rails/test/fixtures/custom_locations.yml +54 -0
- data/vendor/geokit-rails/test/fixtures/locations.yml +54 -0
- data/vendor/geokit-rails/test/fixtures/mock_addresses.yml +17 -0
- data/vendor/geokit-rails/test/fixtures/mock_families.yml +2 -0
- data/vendor/geokit-rails/test/fixtures/mock_houses.yml +9 -0
- data/vendor/geokit-rails/test/fixtures/mock_organizations.yml +5 -0
- data/vendor/geokit-rails/test/fixtures/mock_people.yml +5 -0
- data/vendor/geokit-rails/test/fixtures/stores.yml +0 -0
- data/vendor/geokit-rails/test/ip_geocode_lookup_test.rb +77 -0
- data/vendor/geokit-rails/test/models/company.rb +3 -0
- data/vendor/geokit-rails/test/models/custom_location.rb +12 -0
- data/vendor/geokit-rails/test/models/location.rb +4 -0
- data/vendor/geokit-rails/test/models/mock_address.rb +4 -0
- data/vendor/geokit-rails/test/models/mock_family.rb +3 -0
- data/vendor/geokit-rails/test/models/mock_house.rb +3 -0
- data/vendor/geokit-rails/test/models/mock_organization.rb +4 -0
- data/vendor/geokit-rails/test/models/mock_person.rb +4 -0
- data/vendor/geokit-rails/test/models/store.rb +3 -0
- data/vendor/geokit-rails/test/schema.rb +60 -0
- data/vendor/geokit-rails/test/tasks.rake +31 -0
- data/vendor/geokit-rails/test/test_helper.rb +23 -0
- metadata +476 -0
@@ -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,20 @@
|
|
1
|
+
AircraftManufacturer.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
|
+
end
|
10
|
+
|
11
|
+
process "Derive a list of aircraft manufacturers from aircraft" do
|
12
|
+
Aircraft.run_data_miner!
|
13
|
+
connection.execute %{
|
14
|
+
INSERT IGNORE INTO aircraft_manufacturers(name)
|
15
|
+
SELECT aircraft.manufacturer_name FROM aircraft WHERE LENGTH(aircraft.manufacturer_name) > 0
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Airline < ActiveRecord::Base
|
2
|
+
set_primary_key :iata_code
|
3
|
+
|
4
|
+
# has_many :airline_aircraft, :class_name => 'AirlineAircraft'
|
5
|
+
# has_many :seat_classes, :class_name => 'AirlineSeatClass'
|
6
|
+
has_many :segments, :class_name => "FlightSegment", :foreign_key => 'airline_iata_code'
|
7
|
+
# has_many :airline_aircraft_seat_classes, :class_name => 'AirlineAircraftSeatClass'
|
8
|
+
|
9
|
+
data_miner do
|
10
|
+
tap "Brighter Planet's sanitized airlines data", Earth.taps_server
|
11
|
+
end
|
12
|
+
|
13
|
+
def all_flights_domestic?
|
14
|
+
!international?
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Airline.class_eval do
|
2
|
+
class Airline::Guru
|
3
|
+
# needed by errata
|
4
|
+
def is_not_coral_air?(row); row['Code'].to_i != 19155; end # 19155 Coral Air Inc.: COR
|
5
|
+
def is_not_aviacion_y_comercio?(row); row['Code'].to_i != 19452; end # 19452 Aviacion Y Comercio S.A.: AO
|
6
|
+
def is_not_air_china?(row); row['Code'].to_i != 19543; end # 19543 Air China: CA
|
7
|
+
def is_not_south_african_airways?(row); row['Code'].to_i != 19570; end # 19570 South African Airways: SA
|
8
|
+
def is_not_continental_airlines?(row); row['Code'].to_i != 19704; end # 19704 Continental Air Lines Inc.: CO
|
9
|
+
def is_not_sallee_s_aviation?(row); row['Code'].to_i != 19740; end # 19740 Sallee's Aviation: SAL
|
10
|
+
def is_not_air_berlin?(row); row['Code'].to_i != 21361; end # "21361","Air Berlin PLC and CO: AB"
|
11
|
+
end
|
12
|
+
|
13
|
+
data_miner do
|
14
|
+
schema Earth.database_options do
|
15
|
+
string 'iata_code'
|
16
|
+
string 'name'
|
17
|
+
string 'dot_airline_id_code'
|
18
|
+
boolean 'international'
|
19
|
+
float 'seats'
|
20
|
+
float 'distance'
|
21
|
+
string 'distance_units'
|
22
|
+
float 'load_factor'
|
23
|
+
float 'freight_share'
|
24
|
+
float 'payload'
|
25
|
+
string 'payload_units'
|
26
|
+
end
|
27
|
+
|
28
|
+
import "the T100 AIRLINE_ID lookup table, which also includes IATA codes",
|
29
|
+
:url => 'http://www.transtats.bts.gov/Download_Lookup.asp?Lookup=L_AIRLINE_ID',
|
30
|
+
:errata => Errata.new(:url => 'http://static.brighterplanet.com/science/data/transport/air/airlines/errata.csv',
|
31
|
+
:responder => Airline::Guru.new) do
|
32
|
+
key 'iata_code', :field_name => 'Description', :split => { :pattern => /:/, :keep => 1 }
|
33
|
+
store 'dot_airline_id_code', :field_name => 'Code'
|
34
|
+
store 'name', :field_name => 'Description', :split => { :pattern => /:/, :keep => 0 }
|
35
|
+
end
|
36
|
+
|
37
|
+
process "Determine whether airlines fly internationally by looking at flight segments" do
|
38
|
+
FlightSegment.run_data_miner!
|
39
|
+
update_all 'international = 1', '(SELECT COUNT(*) FROM flight_segments WHERE flight_segments.airline_iata_code = airlines.iata_code AND flight_segments.origin_country_iso_3166_code != flight_segments.dest_country_iso_3166_code AND flight_segments.origin_country_iso_3166_code IS NOT NULL AND flight_segments.dest_country_iso_3166_code IS NOT NULL) > 0'
|
40
|
+
end
|
41
|
+
|
42
|
+
process "Derive some average flight characteristics from flight segments" do
|
43
|
+
FlightSegment.run_data_miner!
|
44
|
+
airlines = Airline.arel_table
|
45
|
+
segments = FlightSegment.arel_table
|
46
|
+
|
47
|
+
conditional_relation = airlines[:iata_code].eq(segments[:airline_iata_code])
|
48
|
+
|
49
|
+
update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
50
|
+
update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
51
|
+
update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
52
|
+
update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
53
|
+
update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).where(conditional_relation).to_sql})"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Airport < ActiveRecord::Base
|
2
|
+
set_primary_key :iata_code
|
3
|
+
|
4
|
+
# --------------------------------
|
5
|
+
# virtual has_many association
|
6
|
+
# has_many :segments won't work because there's no general way to specify the correct conditions
|
7
|
+
# even if you get clever with it, like
|
8
|
+
# has_many :segments,
|
9
|
+
# :class_name => 'FlightSegment',
|
10
|
+
# :foreign_key => 'origin_airport_id',
|
11
|
+
# :conditions => 'flight_segments.destination_airport_id = #{id}'
|
12
|
+
# you get queries like "`flight_segments`.origin_airport_id = 3654 AND (flight_segments.destination_airport_id = 3654))"
|
13
|
+
# in which you notice the AND which must be an OR
|
14
|
+
# and you can't just do finder_sql, because that breaks any other :select
|
15
|
+
def segments
|
16
|
+
FlightSegment.scoped :conditions => ['origin_airport_id = ? OR destination_airport_id = ?', id, id]
|
17
|
+
end
|
18
|
+
# --------------------------------
|
19
|
+
|
20
|
+
belongs_to :country, :foreign_key => 'country_iso_3166_code'
|
21
|
+
acts_as_mappable :default_units => :nms,
|
22
|
+
:lat_column_name => :latitude,
|
23
|
+
:lng_column_name => :longitude
|
24
|
+
|
25
|
+
data_miner do
|
26
|
+
tap "Brighter Planet's sanitized airports data", Earth.taps_server
|
27
|
+
|
28
|
+
process "pull dependencies" do
|
29
|
+
run_data_miner_on_belongs_to_associations
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def all_flights_from_here_domestic?
|
34
|
+
!international_origin?
|
35
|
+
end
|
36
|
+
|
37
|
+
def all_flights_to_here_domestic?
|
38
|
+
!international_destination?
|
39
|
+
end
|
40
|
+
|
41
|
+
def united_states?
|
42
|
+
country == Country.united_states
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
Airport.class_eval do
|
2
|
+
data_miner do
|
3
|
+
schema Earth.database_options do
|
4
|
+
string 'iata_code'
|
5
|
+
string 'name'
|
6
|
+
string 'city'
|
7
|
+
string 'country_name'
|
8
|
+
string 'country_iso_3166_code'
|
9
|
+
float 'latitude'
|
10
|
+
float 'longitude'
|
11
|
+
float 'seats'
|
12
|
+
float 'distance'
|
13
|
+
string 'distance_units'
|
14
|
+
float 'load_factor'
|
15
|
+
float 'freight_share'
|
16
|
+
float 'payload'
|
17
|
+
string 'payload_units'
|
18
|
+
boolean 'international_origin'
|
19
|
+
boolean 'international_destination'
|
20
|
+
end
|
21
|
+
|
22
|
+
import "the OpenFlights.org airports database",
|
23
|
+
:url => 'http://openflights.svn.sourceforge.net/viewvc/openflights/openflights/data/airports.dat',
|
24
|
+
:headers => false,
|
25
|
+
:select => lambda { |row| row[4].present? } do
|
26
|
+
key 'iata_code', :field_number => 4
|
27
|
+
store 'name', :field_number => 1
|
28
|
+
store 'city', :field_number => 2
|
29
|
+
store 'country_name', :field_number => 3
|
30
|
+
store 'country_iso_3166_code', :field_number => 3, :upcase => true, :dictionary => { :input => 'name', :output => 'iso_3166_code', :url => 'http://data.brighterplanet.com/countries.csv' }
|
31
|
+
store 'latitude', :field_number => 6
|
32
|
+
store 'longitude', :field_number => 7
|
33
|
+
end
|
34
|
+
|
35
|
+
# step.await :other_class => FlightSegment do |deferred|
|
36
|
+
# deferred.derive :country # this uses a heuristic that depends on flight segments
|
37
|
+
# class << self
|
38
|
+
# def derive_country
|
39
|
+
# update_all('country_id = (SELECT flight_segments.origin_country_id FROM flight_segments WHERE flight_segments.origin_airport_id = airports.id AND flight_segments.origin_country_id IS NOT NULL LIMIT 1)', 'airports.country_id IS NULL')
|
40
|
+
# update_all('country_id = (SELECT flight_segments.destination_country_id FROM flight_segments WHERE flight_segments.destination_airport_id = airports.id AND flight_segments.destination_country_id IS NOT NULL LIMIT 1)', 'airports.country_id IS NULL')
|
41
|
+
# Country.all.each do |c|
|
42
|
+
# next if c.name.blank?
|
43
|
+
# update_all("country_id = #{c.id}", ["airports.country_id IS NULL AND airports.country_name LIKE ?", "%#{c.name.upcase}%"])
|
44
|
+
# end
|
45
|
+
# Airport.all(:conditions => 'country_id IS NULL AND country_name IS NOT NULL').each do |a|
|
46
|
+
# c = Country.find(:first, :conditions => ["name like ?", "%#{a.country_name}%"])
|
47
|
+
# a.update_attributes(:country_id => c.id) if c
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
|
52
|
+
process "Determine whether each airport serves international flights" do
|
53
|
+
FlightSegment.run_data_miner!
|
54
|
+
update_all 'international_origin = 1', '(SELECT COUNT(*) FROM flight_segments WHERE flight_segments.origin_airport_iata_code = airports.iata_code AND flight_segments.origin_country_iso_3166_code != flight_segments.dest_country_iso_3166_code AND flight_segments.origin_country_iso_3166_code IS NOT NULL AND flight_segments.dest_country_iso_3166_code IS NOT NULL LIMIT 1) > 0'
|
55
|
+
update_all 'international_destination = 1', '(SELECT COUNT(*) FROM flight_segments WHERE flight_segments.dest_airport_iata_code = airports.iata_code AND flight_segments.origin_country_iso_3166_code != flight_segments.dest_country_iso_3166_code AND flight_segments.origin_country_iso_3166_code IS NOT NULL AND flight_segments.dest_country_iso_3166_code IS NOT NULL LIMIT 1) > 0'
|
56
|
+
end
|
57
|
+
|
58
|
+
# sabshere 5/24/10 using temporary tables because the WHERE clause has a very slow OR condition: iata_code = dest_iata_code OR iata_code = origin_iata_code
|
59
|
+
process "Derive some average flight characteristics from flight segments" do
|
60
|
+
FlightSegment.run_data_miner!
|
61
|
+
segments = FlightSegment.arel_table
|
62
|
+
airports = Airport.arel_table
|
63
|
+
|
64
|
+
find_in_batches do |batch|
|
65
|
+
batch.each do |airport|
|
66
|
+
targeting_relation = airports[:iata_code].eq airport.iata_code
|
67
|
+
conditional_relation = segments[:origin_airport_iata_code].eq(airport.iata_code).or(segments[:dest_airport_iata_code].eq(airport.iata_code))
|
68
|
+
connection.execute "CREATE TEMPORARY TABLE tmp1 #{FlightSegment.where(conditional_relation).to_sql}"
|
69
|
+
update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
70
|
+
update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
71
|
+
update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
72
|
+
update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
73
|
+
update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
74
|
+
connection.execute 'DROP TABLE tmp1'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'earth/locality'
|
2
|
+
require 'earth/locality/data_miner'
|
3
|
+
require 'earth/air/aircraft/data_miner'
|
4
|
+
require 'earth/air/aircraft_class/data_miner'
|
5
|
+
require 'earth/air/aircraft_manufacturer/data_miner'
|
6
|
+
require 'earth/air/airline/data_miner'
|
7
|
+
require 'earth/air/airport/data_miner'
|
8
|
+
require 'earth/air/flight_configuration/data_miner'
|
9
|
+
require 'earth/air/flight_distance_class/data_miner'
|
10
|
+
require 'earth/air/flight_domesticity/data_miner'
|
11
|
+
require 'earth/air/flight_fuel_type/data_miner'
|
12
|
+
require 'earth/air/flight_propulsion/data_miner'
|
13
|
+
require 'earth/air/flight_seat_class/data_miner'
|
14
|
+
require 'earth/air/flight_segment/data_miner'
|
15
|
+
require 'earth/air/flight_service/data_miner'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
FlightConfiguration.class_eval do
|
2
|
+
data_miner do
|
3
|
+
schema do
|
4
|
+
string 'name'
|
5
|
+
string 'bts_aircraft_configuration_code'
|
6
|
+
end
|
7
|
+
|
8
|
+
process "derive from flight segments" do
|
9
|
+
FlightSegment.run_data_miner!
|
10
|
+
connection.execute %{
|
11
|
+
INSERT IGNORE INTO flight_configurations(name, bts_aircraft_configuration_code)
|
12
|
+
SELECT flight_segments.configuration_id, flight_segments.bts_aircraft_configuration_code FROM flight_segments WHERE LENGTH(flight_segments.configuration_id) > 0
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
FlightDistanceClass.class_eval do
|
2
|
+
data_miner do
|
3
|
+
schema Earth.database_options do
|
4
|
+
string 'name'
|
5
|
+
float 'distance'
|
6
|
+
string 'distance_units'
|
7
|
+
end
|
8
|
+
|
9
|
+
import "a list of Brighter Planet-defined distance classes",
|
10
|
+
:url => 'http://static.brighterplanet.com/science/data/transport/air/distance_classes/distance_classes.csv' do
|
11
|
+
key 'name'
|
12
|
+
store 'distance', :units_field_name => 'units', :to_units => :kilometres
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
FlightDomesticity.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 'bts_data_source_code'
|
10
|
+
float 'distance'
|
11
|
+
string 'distance_units'
|
12
|
+
float 'freight_share'
|
13
|
+
float 'load_factor'
|
14
|
+
float 'seats'
|
15
|
+
float 'payload'
|
16
|
+
string 'payload_units'
|
17
|
+
end
|
18
|
+
|
19
|
+
process "Derive flight domesticities from flight segments" do # FIXME TODO might make more sense to combine foreign and domestic carriers -> domestic flight (all carriers), international flight (all carriers)
|
20
|
+
FlightSegment.run_data_miner!
|
21
|
+
connection.execute %{
|
22
|
+
INSERT IGNORE INTO flight_domesticities(name, bts_data_source_code)
|
23
|
+
SELECT flight_segments.domesticity_id, flight_segments.bts_data_source_code FROM flight_segments WHERE LENGTH(flight_segments.domesticity_id) > 0
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
process "Derive average flight characteristics from flight segments" do
|
28
|
+
FlightSegment.run_data_miner!
|
29
|
+
segments = FlightSegment.arel_table
|
30
|
+
flight_domesticities = FlightDomesticity.arel_table
|
31
|
+
## slow, all-in-one method
|
32
|
+
# conditional_relation = flight_domesticities[:name].eq(segments[:domesticity_id])
|
33
|
+
# update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
34
|
+
# update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
35
|
+
# update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
36
|
+
# update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
|
37
|
+
# update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).where(conditional_relation).to_sql})"
|
38
|
+
## fast method using temp tables
|
39
|
+
find_in_batches do |batch|
|
40
|
+
batch.each do |flight_domesticity|
|
41
|
+
targeting_relation = flight_domesticities[:name].eq flight_domesticity.name
|
42
|
+
conditional_relation = segments[:domesticity_id].eq flight_domesticity.name
|
43
|
+
connection.execute "CREATE TEMPORARY TABLE tmp1 #{FlightSegment.where(conditional_relation).to_sql}"
|
44
|
+
update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
45
|
+
update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
46
|
+
update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
47
|
+
update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
48
|
+
update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).to_sql.gsub('flight_segments', 'tmp1')})", targeting_relation.to_sql
|
49
|
+
connection.execute 'DROP TABLE tmp1'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
update_all "distance_units = 'kilometres'"
|
53
|
+
update_all "payload_units = 'kilograms'"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class FlightFuelType < ActiveRecord::Base
|
2
|
+
# this fallback is jet fuel
|
3
|
+
falls_back_on :emission_factor => (21.09.pounds.to(:kilograms) / 1.gallons.to(:litres)), # in pounds CO2/gallon fuel: http://www.eia.doe.gov/oiaf/1605/excel/Fuel%20Emission%20Factors.xls
|
4
|
+
:radiative_forcing_index => 2, # from Matt
|
5
|
+
:density => 3.057 # kg / gal
|
6
|
+
|
7
|
+
data_miner do
|
8
|
+
tap "Brighter Planet's sanitized flight fuel type data", Earth.taps_server
|
9
|
+
|
10
|
+
# we just always use the fallback
|
11
|
+
end
|
12
|
+
end
|