earth 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
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,31 @@
1
+ module Geokit
2
+ module Adapters
3
+ class Abstract
4
+ class NotImplementedError < StandardError ; end
5
+
6
+ cattr_accessor :loaded
7
+
8
+ class << self
9
+ def load(klass) ; end
10
+ end
11
+
12
+ def initialize(klass)
13
+ @owner = klass
14
+ end
15
+
16
+ def method_missing(method, *args, &block)
17
+ return @owner.send(method, *args, &block) if @owner.respond_to?(method)
18
+ super
19
+ end
20
+
21
+ def sphere_distance_sql(lat, lng, multiplier)
22
+ raise NotImplementedError, '#sphere_distance_sql is not implemented'
23
+ end
24
+
25
+ def flat_distance_sql(origin, lat_degree_units, lng_degree_units)
26
+ raise NotImplementedError, '#flat_distance_sql is not implemented'
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ module Geokit
2
+ module Adapters
3
+ class MySQL < Abstract
4
+
5
+ def sphere_distance_sql(lat, lng, multiplier)
6
+ %|
7
+ (ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
8
+ COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
9
+ SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
10
+ |
11
+ end
12
+
13
+ def flat_distance_sql(origin, lat_degree_units, lng_degree_units)
14
+ %|
15
+ SQRT(POW(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
16
+ POW(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
17
+ |
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Geokit
2
+ module Adapters
3
+ class PostgreSQL < Abstract
4
+
5
+ def sphere_distance_sql(lat, lng, multiplier)
6
+ %|
7
+ (ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
8
+ COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
9
+ SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
10
+ |
11
+ end
12
+
13
+ def flat_distance_sql(origin, lat_degree_units, lng_degree_units)
14
+ %|
15
+ SQRT(POW(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
16
+ POW(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
17
+ |
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,43 @@
1
+ module Geokit
2
+ module Adapters
3
+ class SQLServer < Abstract
4
+
5
+ class << self
6
+
7
+ def load(klass)
8
+ klass.connection.execute <<-EOS
9
+ if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[geokit_least]') and xtype in (N'FN', N'IF', N'TF'))
10
+ drop function [dbo].[geokit_least]
11
+ EOS
12
+
13
+ klass.connection.execute <<-EOS
14
+ CREATE FUNCTION [dbo].geokit_least (@value1 float,@value2 float) RETURNS float AS BEGIN
15
+ return (SELECT CASE WHEN @value1 < @value2 THEN @value1 ELSE @value2 END) END
16
+ EOS
17
+ self.loaded = true
18
+ end
19
+
20
+ end
21
+
22
+ def initialize(*args)
23
+ super(*args)
24
+ end
25
+
26
+ def sphere_distance_sql(lat, lng, multiplier)
27
+ %|
28
+ (ACOS([dbo].geokit_least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
29
+ COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
30
+ SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
31
+ |
32
+ end
33
+
34
+ def flat_distance_sql(origin, lat_degree_units, lng_degree_units)
35
+ %|
36
+ SQRT(POWER(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
37
+ POWER(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
38
+ |
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ module Geokit
2
+ # These defaults are used in Geokit::Mappable.distance_to and in acts_as_mappable
3
+ @@default_units = :miles
4
+ @@default_formula = :sphere
5
+
6
+ [:default_units, :default_formula].each do |sym|
7
+ class_eval <<-EOS, __FILE__, __LINE__
8
+ def self.#{sym}
9
+ if defined?(#{sym.to_s.upcase})
10
+ #{sym.to_s.upcase}
11
+ else
12
+ @@#{sym}
13
+ end
14
+ end
15
+
16
+ def self.#{sym}=(obj)
17
+ @@#{sym} = obj
18
+ end
19
+ EOS
20
+ end
21
+ Geokit::Geocoders.logger = ActiveRecord::Base.logger
22
+ end
@@ -0,0 +1,16 @@
1
+ module Geokit
2
+ module GeocoderControl
3
+ def set_geokit_domain
4
+ Geokit::Geocoders::domain = request.domain
5
+ logger.debug("Geokit is using the domain: #{Geokit::Geocoders::domain}")
6
+ end
7
+
8
+ def self.included(base)
9
+ if base.respond_to? :before_filter
10
+ base.send :before_filter, :set_geokit_domain
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ ActionController::Base.send(:include, Geokit::GeocoderControl) if defined?(ActionController::Base)
@@ -0,0 +1,46 @@
1
+ require 'yaml'
2
+
3
+ module Geokit
4
+ # Contains a class method geocode_ip_address which can be used to enable automatic geocoding
5
+ # for request IP addresses. The geocoded information is stored in a cookie and in the
6
+ # session to minimize web service calls. The point of the helper is to enable location-based
7
+ # websites to have a best-guess for new visitors.
8
+ module IpGeocodeLookup
9
+ # Mix below class methods into ActionController.
10
+ def self.included(base) # :nodoc:
11
+ base.extend ClassMethods
12
+ end
13
+
14
+ # Class method to mix into active record.
15
+ module ClassMethods # :nodoc:
16
+ def geocode_ip_address(filter_options = {})
17
+ before_filter :store_ip_location, filter_options
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Places the IP address' geocode location into the session if it
24
+ # can be found. Otherwise, looks for a geo location cookie and
25
+ # uses that value. The last resort is to call the web service to
26
+ # get the value.
27
+ def store_ip_location
28
+ session[:geo_location] ||= retrieve_location_from_cookie_or_service
29
+ cookies[:geo_location] = { :value => session[:geo_location].to_yaml, :expires => 30.days.from_now } if session[:geo_location]
30
+ end
31
+
32
+ # Uses the stored location value from the cookie if it exists. If
33
+ # no cookie exists, calls out to the web service to get the location.
34
+ def retrieve_location_from_cookie_or_service
35
+ return YAML.load(cookies[:geo_location]) if cookies[:geo_location]
36
+ location = Geocoders::MultiGeocoder.geocode(get_ip_address)
37
+ return location.success ? location : nil
38
+ end
39
+
40
+ # Returns the real ip address, though this could be the localhost ip
41
+ # address. No special handling here anymore.
42
+ def get_ip_address
43
+ request.remote_ip
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,474 @@
1
+ require 'test_helper'
2
+
3
+
4
+ Geokit::Geocoders::provider_order = [:google, :us]
5
+
6
+ class ActsAsMappableTest < GeokitTestCase
7
+
8
+ LOCATION_A_IP = "217.10.83.5"
9
+
10
+ def setup
11
+ @location_a = GeoKit::GeoLoc.new
12
+ @location_a.lat = 32.918593
13
+ @location_a.lng = -96.958444
14
+ @location_a.city = "Irving"
15
+ @location_a.state = "TX"
16
+ @location_a.country_code = "US"
17
+ @location_a.success = true
18
+
19
+ @sw = GeoKit::LatLng.new(32.91663,-96.982841)
20
+ @ne = GeoKit::LatLng.new(32.96302,-96.919495)
21
+ @bounds_center=GeoKit::LatLng.new((@sw.lat+@ne.lat)/2,(@sw.lng+@ne.lng)/2)
22
+
23
+ @starbucks = companies(:starbucks)
24
+ @loc_a = locations(:a)
25
+ @custom_loc_a = custom_locations(:a)
26
+ @loc_e = locations(:e)
27
+ @custom_loc_e = custom_locations(:e)
28
+
29
+ @barnes_and_noble = mock_organizations(:barnes_and_noble)
30
+ @address = mock_addresses(:address_barnes_and_noble)
31
+ end
32
+
33
+ def test_override_default_units_the_hard_way
34
+ Location.default_units = :kms
35
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
36
+ assert_equal 5, locations.size
37
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 3.97")
38
+ assert_equal 5, locations
39
+ Location.default_units = :miles
40
+ end
41
+
42
+ def test_include
43
+ locations = Location.find(:all, :origin => @loc_a, :include => :company, :conditions => "company_id = 1")
44
+ assert !locations.empty?
45
+ assert_equal 1, locations[0].company.id
46
+ assert_equal 'Starbucks', locations[0].company.name
47
+ end
48
+
49
+ def test_distance_between_geocoded
50
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
51
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("San Francisco, CA").returns(@location_a)
52
+ assert_equal 0, Location.distance_between("Irving, TX", "San Francisco, CA")
53
+ end
54
+
55
+ def test_distance_to_geocoded
56
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
57
+ assert_equal 0, @custom_loc_a.distance_to("Irving, TX")
58
+ end
59
+
60
+ def test_distance_to_geocoded_error
61
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(GeoKit::GeoLoc.new)
62
+ assert_raise(GeoKit::Geocoders::GeocodeError) { @custom_loc_a.distance_to("Irving, TX") }
63
+ end
64
+
65
+ def test_custom_attributes_distance_calculations
66
+ assert_equal 0, @custom_loc_a.distance_to(@loc_a)
67
+ assert_equal 0, CustomLocation.distance_between(@custom_loc_a, @loc_a)
68
+ end
69
+
70
+ def test_distance_column_in_select
71
+ locations = Location.find(:all, :origin => @loc_a, :order => "distance ASC")
72
+ assert_equal 6, locations.size
73
+ assert_equal 0, @loc_a.distance_to(locations.first)
74
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
75
+ end
76
+
77
+ def test_find_with_distance_condition
78
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
79
+ assert_equal 5, locations.size
80
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 3.97")
81
+ assert_equal 5, locations
82
+ end
83
+
84
+ def test_find_with_distance_condition_with_units_override
85
+ locations = Location.find(:all, :origin => @loc_a, :units => :kms, :conditions => "distance < 6.387")
86
+ assert_equal 5, locations.size
87
+ locations = Location.count(:origin => @loc_a, :units => :kms, :conditions => "distance < 6.387")
88
+ assert_equal 5, locations
89
+ end
90
+
91
+ def test_find_with_distance_condition_with_formula_override
92
+ locations = Location.find(:all, :origin => @loc_a, :formula => :flat, :conditions => "distance < 6.387")
93
+ assert_equal 6, locations.size
94
+ locations = Location.count(:origin => @loc_a, :formula => :flat, :conditions => "distance < 6.387")
95
+ assert_equal 6, locations
96
+ end
97
+
98
+ def test_find_within
99
+ locations = Location.find_within(3.97, :origin => @loc_a)
100
+ assert_equal 5, locations.size
101
+ locations = Location.count_within(3.97, :origin => @loc_a)
102
+ assert_equal 5, locations
103
+ end
104
+
105
+ def test_find_within_with_token
106
+ locations = Location.find(:all, :within => 3.97, :origin => @loc_a)
107
+ assert_equal 5, locations.size
108
+ locations = Location.count(:within => 3.97, :origin => @loc_a)
109
+ assert_equal 5, locations
110
+ end
111
+
112
+ def test_find_within_with_coordinates
113
+ locations = Location.find_within(3.97, :origin =>[@loc_a.lat,@loc_a.lng])
114
+ assert_equal 5, locations.size
115
+ locations = Location.count_within(3.97, :origin =>[@loc_a.lat,@loc_a.lng])
116
+ assert_equal 5, locations
117
+ end
118
+
119
+ def test_find_with_compound_condition
120
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
121
+ assert_equal 2, locations.size
122
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
123
+ assert_equal 2, locations
124
+ end
125
+
126
+ def test_find_with_secure_compound_condition
127
+ locations = Location.find(:all, :origin => @loc_a, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
128
+ assert_equal 2, locations.size
129
+ locations = Location.count(:origin => @loc_a, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
130
+ assert_equal 2, locations
131
+ end
132
+
133
+ def test_find_beyond
134
+ locations = Location.find_beyond(3.95, :origin => @loc_a)
135
+ assert_equal 1, locations.size
136
+ locations = Location.count_beyond(3.95, :origin => @loc_a)
137
+ assert_equal 1, locations
138
+ end
139
+
140
+ def test_find_beyond_with_token
141
+ locations = Location.find(:all, :beyond => 3.95, :origin => @loc_a)
142
+ assert_equal 1, locations.size
143
+ locations = Location.count(:beyond => 3.95, :origin => @loc_a)
144
+ assert_equal 1, locations
145
+ end
146
+
147
+ def test_find_beyond_with_coordinates
148
+ locations = Location.find_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
149
+ assert_equal 1, locations.size
150
+ locations = Location.count_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
151
+ assert_equal 1, locations
152
+ end
153
+
154
+ def test_find_range_with_token
155
+ locations = Location.find(:all, :range => 0..10, :origin => @loc_a)
156
+ assert_equal 6, locations.size
157
+ locations = Location.count(:range => 0..10, :origin => @loc_a)
158
+ assert_equal 6, locations
159
+ end
160
+
161
+ def test_find_range_with_token_with_conditions
162
+ locations = Location.find(:all, :origin => @loc_a, :range => 0..10, :conditions => ["city = ?", 'Coppell'])
163
+ assert_equal 2, locations.size
164
+ locations = Location.count(:origin => @loc_a, :range => 0..10, :conditions => ["city = ?", 'Coppell'])
165
+ assert_equal 2, locations
166
+ end
167
+
168
+ def test_find_range_with_token_with_hash_conditions
169
+ locations = Location.find(:all, :origin => @loc_a, :range => 0..10, :conditions => {:city => 'Coppell'})
170
+ assert_equal 2, locations.size
171
+ locations = Location.count(:origin => @loc_a, :range => 0..10, :conditions => {:city => 'Coppell'})
172
+ assert_equal 2, locations
173
+ end
174
+
175
+ def test_find_range_with_token_excluding_end
176
+ locations = Location.find(:all, :range => 0...10, :origin => @loc_a)
177
+ assert_equal 6, locations.size
178
+ locations = Location.count(:range => 0...10, :origin => @loc_a)
179
+ assert_equal 6, locations
180
+ end
181
+
182
+ def test_find_nearest
183
+ assert_equal @loc_a, Location.find_nearest(:origin => @loc_a)
184
+ end
185
+
186
+ def test_find_nearest_through_find
187
+ assert_equal @loc_a, Location.find(:nearest, :origin => @loc_a)
188
+ end
189
+
190
+ def test_find_nearest_with_coordinates
191
+ assert_equal @loc_a, Location.find_nearest(:origin =>[@loc_a.lat, @loc_a.lng])
192
+ end
193
+
194
+ def test_find_farthest
195
+ assert_equal @loc_e, Location.find_farthest(:origin => @loc_a)
196
+ end
197
+
198
+ def test_find_farthest_through_find
199
+ assert_equal @loc_e, Location.find(:farthest, :origin => @loc_a)
200
+ end
201
+
202
+ def test_find_farthest_with_coordinates
203
+ assert_equal @loc_e, Location.find_farthest(:origin =>[@loc_a.lat, @loc_a.lng])
204
+ end
205
+
206
+ def test_scoped_distance_column_in_select
207
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :order => "distance ASC")
208
+ assert_equal 5, locations.size
209
+ assert_equal 0, @loc_a.distance_to(locations.first)
210
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
211
+ end
212
+
213
+ def test_scoped_find_with_distance_condition
214
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
215
+ assert_equal 4, locations.size
216
+ locations = @starbucks.locations.count(:origin => @loc_a, :conditions => "distance < 3.97")
217
+ assert_equal 4, locations
218
+ end
219
+
220
+ def test_scoped_find_within
221
+ locations = @starbucks.locations.find_within(3.97, :origin => @loc_a)
222
+ assert_equal 4, locations.size
223
+ locations = @starbucks.locations.count_within(3.97, :origin => @loc_a)
224
+ assert_equal 4, locations
225
+ end
226
+
227
+ def test_scoped_find_with_compound_condition
228
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
229
+ assert_equal 2, locations.size
230
+ locations = @starbucks.locations.count( :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
231
+ assert_equal 2, locations
232
+ end
233
+
234
+ def test_scoped_find_beyond
235
+ locations = @starbucks.locations.find_beyond(3.95, :origin => @loc_a)
236
+ assert_equal 1, locations.size
237
+ locations = @starbucks.locations.count_beyond(3.95, :origin => @loc_a)
238
+ assert_equal 1, locations
239
+ end
240
+
241
+ def test_scoped_find_nearest
242
+ assert_equal @loc_a, @starbucks.locations.find_nearest(:origin => @loc_a)
243
+ end
244
+
245
+ def test_scoped_find_farthest
246
+ assert_equal @loc_e, @starbucks.locations.find_farthest(:origin => @loc_a)
247
+ end
248
+
249
+ def test_ip_geocoded_distance_column_in_select
250
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
251
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :order => "distance ASC")
252
+ assert_equal 6, locations.size
253
+ assert_equal 0, @loc_a.distance_to(locations.first)
254
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
255
+ end
256
+
257
+ def test_ip_geocoded_find_with_distance_condition
258
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
259
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => "distance < 3.97")
260
+ assert_equal 5, locations.size
261
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
262
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => "distance < 3.97")
263
+ assert_equal 5, locations
264
+ end
265
+
266
+ def test_ip_geocoded_find_within
267
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
268
+ locations = Location.find_within(3.97, :origin => LOCATION_A_IP)
269
+ assert_equal 5, locations.size
270
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
271
+ locations = Location.count_within(3.97, :origin => LOCATION_A_IP)
272
+ assert_equal 5, locations
273
+ end
274
+
275
+ def test_ip_geocoded_find_with_compound_condition
276
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
277
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => "distance < 5 and city = 'Coppell'")
278
+ assert_equal 2, locations.size
279
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
280
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => "distance < 5 and city = 'Coppell'")
281
+ assert_equal 2, locations
282
+ end
283
+
284
+ def test_ip_geocoded_find_with_secure_compound_condition
285
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
286
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
287
+ assert_equal 2, locations.size
288
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
289
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
290
+ assert_equal 2, locations
291
+ end
292
+
293
+ def test_ip_geocoded_find_beyond
294
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
295
+ locations = Location.find_beyond(3.95, :origin => LOCATION_A_IP)
296
+ assert_equal 1, locations.size
297
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
298
+ locations = Location.count_beyond(3.95, :origin => LOCATION_A_IP)
299
+ assert_equal 1, locations
300
+ end
301
+
302
+ def test_ip_geocoded_find_nearest
303
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
304
+ assert_equal @loc_a, Location.find_nearest(:origin => LOCATION_A_IP)
305
+ end
306
+
307
+ def test_ip_geocoded_find_farthest
308
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
309
+ assert_equal @loc_e, Location.find_farthest(:origin => LOCATION_A_IP)
310
+ end
311
+
312
+ def test_ip_geocoder_exception
313
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with('127.0.0.1').returns(GeoKit::GeoLoc.new)
314
+ assert_raises GeoKit::Geocoders::GeocodeError do
315
+ Location.find_farthest(:origin => '127.0.0.1')
316
+ end
317
+ end
318
+
319
+ def test_address_geocode
320
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with('Irving, TX').returns(@location_a)
321
+ locations = Location.find(:all, :origin => 'Irving, TX', :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
322
+ assert_equal 2, locations.size
323
+ end
324
+
325
+ def test_find_with_custom_distance_condition
326
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => "dist < 3.97")
327
+ assert_equal 5, locations.size
328
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => "dist < 3.97")
329
+ assert_equal 5, locations
330
+ end
331
+
332
+ def test_find_with_custom_distance_condition_using_custom_origin
333
+ locations = CustomLocation.find(:all, :origin => @custom_loc_a, :conditions => "dist < 3.97")
334
+ assert_equal 5, locations.size
335
+ locations = CustomLocation.count(:origin => @custom_loc_a, :conditions => "dist < 3.97")
336
+ assert_equal 5, locations
337
+ end
338
+
339
+ def test_find_within_with_custom
340
+ locations = CustomLocation.find_within(3.97, :origin => @loc_a)
341
+ assert_equal 5, locations.size
342
+ locations = CustomLocation.count_within(3.97, :origin => @loc_a)
343
+ assert_equal 5, locations
344
+ end
345
+
346
+ def test_find_within_with_coordinates_with_custom
347
+ locations = CustomLocation.find_within(3.97, :origin =>[@loc_a.lat, @loc_a.lng])
348
+ assert_equal 5, locations.size
349
+ locations = CustomLocation.count_within(3.97, :origin =>[@loc_a.lat, @loc_a.lng])
350
+ assert_equal 5, locations
351
+ end
352
+
353
+ def test_find_with_compound_condition_with_custom
354
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => "dist < 5 and city = 'Coppell'")
355
+ assert_equal 1, locations.size
356
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => "dist < 5 and city = 'Coppell'")
357
+ assert_equal 1, locations
358
+ end
359
+
360
+ def test_find_with_secure_compound_condition_with_custom
361
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => ["dist < ? and city = ?", 5, 'Coppell'])
362
+ assert_equal 1, locations.size
363
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => ["dist < ? and city = ?", 5, 'Coppell'])
364
+ assert_equal 1, locations
365
+ end
366
+
367
+ def test_find_beyond_with_custom
368
+ locations = CustomLocation.find_beyond(3.95, :origin => @loc_a)
369
+ assert_equal 1, locations.size
370
+ locations = CustomLocation.count_beyond(3.95, :origin => @loc_a)
371
+ assert_equal 1, locations
372
+ end
373
+
374
+ def test_find_beyond_with_coordinates_with_custom
375
+ locations = CustomLocation.find_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
376
+ assert_equal 1, locations.size
377
+ locations = CustomLocation.count_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
378
+ assert_equal 1, locations
379
+ end
380
+
381
+ def test_find_nearest_with_custom
382
+ assert_equal @custom_loc_a, CustomLocation.find_nearest(:origin => @loc_a)
383
+ end
384
+
385
+ def test_find_nearest_with_coordinates_with_custom
386
+ assert_equal @custom_loc_a, CustomLocation.find_nearest(:origin =>[@loc_a.lat, @loc_a.lng])
387
+ end
388
+
389
+ def test_find_farthest_with_custom
390
+ assert_equal @custom_loc_e, CustomLocation.find_farthest(:origin => @loc_a)
391
+ end
392
+
393
+ def test_find_farthest_with_coordinates_with_custom
394
+ assert_equal @custom_loc_e, CustomLocation.find_farthest(:origin =>[@loc_a.lat, @loc_a.lng])
395
+ end
396
+
397
+ def test_find_with_array_origin
398
+ locations = Location.find(:all, :origin =>[@loc_a.lat,@loc_a.lng], :conditions => "distance < 3.97")
399
+ assert_equal 5, locations.size
400
+ locations = Location.count(:origin =>[@loc_a.lat,@loc_a.lng], :conditions => "distance < 3.97")
401
+ assert_equal 5, locations
402
+ end
403
+
404
+
405
+ # Bounding box tests
406
+
407
+ def test_find_within_bounds
408
+ locations = Location.find_within_bounds([@sw,@ne])
409
+ assert_equal 2, locations.size
410
+ locations = Location.count_within_bounds([@sw,@ne])
411
+ assert_equal 2, locations
412
+ end
413
+
414
+ def test_find_within_bounds_ordered_by_distance
415
+ locations = Location.find_within_bounds([@sw,@ne], :origin=>@bounds_center, :order=>'distance asc')
416
+ assert_equal locations[0], locations(:d)
417
+ assert_equal locations[1], locations(:a)
418
+ end
419
+
420
+ def test_find_within_bounds_with_token
421
+ locations = Location.find(:all, :bounds=>[@sw,@ne])
422
+ assert_equal 2, locations.size
423
+ locations = Location.count(:bounds=>[@sw,@ne])
424
+ assert_equal 2, locations
425
+ end
426
+
427
+ def test_find_within_bounds_with_string_conditions
428
+ locations = Location.find(:all, :bounds=>[@sw,@ne], :conditions=>"id !=#{locations(:a).id}")
429
+ assert_equal 1, locations.size
430
+ end
431
+
432
+ def test_find_within_bounds_with_array_conditions
433
+ locations = Location.find(:all, :bounds=>[@sw,@ne], :conditions=>["id != ?", locations(:a).id])
434
+ assert_equal 1, locations.size
435
+ end
436
+
437
+ def test_find_within_bounds_with_hash_conditions
438
+ locations = Location.find(:all, :bounds=>[@sw,@ne], :conditions=>{:id => locations(:a).id})
439
+ assert_equal 1, locations.size
440
+ end
441
+
442
+ def test_auto_geocode
443
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
444
+ store=Store.new(:address=>'Irving, TX')
445
+ store.save
446
+ assert_equal store.lat,@location_a.lat
447
+ assert_equal store.lng,@location_a.lng
448
+ assert_equal 0, store.errors.size
449
+ end
450
+
451
+ def test_auto_geocode_failure
452
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("BOGUS").returns(GeoKit::GeoLoc.new)
453
+ store=Store.new(:address=>'BOGUS')
454
+ store.save
455
+ assert store.new_record?
456
+ assert_equal 1, store.errors.size
457
+ end
458
+
459
+ # Test :through
460
+
461
+ def test_find_with_through
462
+ organizations = MockOrganization.find(:all, :origin => @location_a, :order => 'distance ASC')
463
+ assert_equal 2, organizations.size
464
+ organizations = MockOrganization.count(:origin => @location_a, :conditions => "distance < 3.97")
465
+ assert_equal 1, organizations
466
+ end
467
+
468
+ def test_find_with_through_with_hash
469
+ people = MockPerson.find(:all, :origin => @location_a, :order => 'distance ASC')
470
+ assert_equal 2, people.size
471
+ people = MockPerson.count(:origin => @location_a, :conditions => "distance < 3.97")
472
+ assert_equal 2, people
473
+ end
474
+ end