geokit 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +6 -14
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +11 -0
  4. data/Gemfile +2 -1
  5. data/MIT-LICENSE +20 -0
  6. data/README.markdown +44 -39
  7. data/Rakefile +15 -0
  8. data/fixtures/vcr_cassettes/bing_full.yml +102 -0
  9. data/fixtures/vcr_cassettes/bing_full_au.yml +91 -0
  10. data/fixtures/vcr_cassettes/bing_full_de.yml +91 -0
  11. data/fixtures/vcr_cassettes/fcc_reverse_geocode.yml +37 -0
  12. data/fixtures/vcr_cassettes/free_geo_ip_geocode.yml +36 -0
  13. data/fixtures/vcr_cassettes/geo_plugin_geocode.yml +38 -0
  14. data/fixtures/vcr_cassettes/geonames_geocode.yml +304 -0
  15. data/fixtures/vcr_cassettes/{google3_city.yml → google_city.yml} +0 -0
  16. data/fixtures/vcr_cassettes/{google3_country_code_biased_result.yml → google_country_code_biased_result.yml} +0 -0
  17. data/fixtures/vcr_cassettes/{google3_full.yml → google_full.yml} +0 -0
  18. data/fixtures/vcr_cassettes/{google3_full_short.yml → google_full_short.yml} +0 -0
  19. data/fixtures/vcr_cassettes/{google3_language_response_fr.yml → google_language_response_fr.yml} +0 -0
  20. data/fixtures/vcr_cassettes/{google3_multi.yml → google_multi.yml} +0 -0
  21. data/fixtures/vcr_cassettes/{google3_reverse_madrid.yml → google_reverse_madrid.yml} +0 -0
  22. data/fixtures/vcr_cassettes/ripe_geocode.yml +66 -0
  23. data/fixtures/vcr_cassettes/ripe_geocode_au.yml +66 -0
  24. data/geokit.gemspec +1 -1
  25. data/lib/geokit.rb +5 -0
  26. data/lib/geokit/bounds.rb +96 -0
  27. data/lib/geokit/core_ext.rb +17 -0
  28. data/lib/geokit/geo_loc.rb +134 -0
  29. data/lib/geokit/geocoders.rb +48 -35
  30. data/lib/geokit/geocoders/base_ip.rb +43 -0
  31. data/lib/geokit/geocoders/bing.rb +101 -0
  32. data/lib/geokit/geocoders/ca_geocoder.rb +50 -0
  33. data/lib/geokit/{services → geocoders}/fcc.rb +17 -20
  34. data/lib/geokit/geocoders/free_geo_ip.rb +34 -0
  35. data/lib/geokit/geocoders/geo_plugin.rb +33 -0
  36. data/lib/geokit/geocoders/geonames.rb +53 -0
  37. data/lib/geokit/{services/google3.rb → geocoders/google.rb} +59 -57
  38. data/lib/geokit/geocoders/ip.rb +69 -0
  39. data/lib/geokit/geocoders/mapquest.rb +72 -0
  40. data/lib/geokit/geocoders/maxmind.rb +29 -0
  41. data/lib/geokit/geocoders/openstreetmap.rb +119 -0
  42. data/lib/geokit/geocoders/ripe.rb +41 -0
  43. data/lib/geokit/{services → geocoders}/us_geocoder.rb +15 -20
  44. data/lib/geokit/{services → geocoders}/yahoo.rb +52 -55
  45. data/lib/geokit/geocoders/yandex.rb +61 -0
  46. data/lib/geokit/inflectors.rb +1 -2
  47. data/lib/geokit/lat_lng.rb +129 -0
  48. data/lib/geokit/mappable.rb +41 -424
  49. data/lib/geokit/multi_geocoder.rb +6 -2
  50. data/lib/geokit/polygon.rb +46 -0
  51. data/lib/geokit/version.rb +1 -1
  52. data/test/helper.rb +2 -12
  53. data/test/test_base_geocoder.rb +0 -10
  54. data/test/test_bing_geocoder.rb +60 -0
  55. data/test/test_fcc_geocoder.rb +23 -0
  56. data/test/test_free_geo_ip_geocoder.rb +23 -0
  57. data/test/test_geo_plugin_geocoder.rb +23 -0
  58. data/test/test_geonames_geocoder.rb +23 -0
  59. data/test/test_google_geocoder.rb +208 -235
  60. data/test/test_maxmind_geocoder.rb +35 -4
  61. data/test/test_multi_geocoder.rb +3 -1
  62. data/test/test_ripe_geocoder.rb +35 -0
  63. data/test/test_yahoo_geocoder.rb +0 -12
  64. metadata +78 -52
  65. data/LICENSE +0 -25
  66. data/Manifest.txt +0 -21
  67. data/data/GeoLiteCity.dat +0 -0
  68. data/lib/geokit/services/ca_geocoder.rb +0 -55
  69. data/lib/geokit/services/geo_plugin.rb +0 -31
  70. data/lib/geokit/services/geonames.rb +0 -53
  71. data/lib/geokit/services/google.rb +0 -158
  72. data/lib/geokit/services/ip.rb +0 -103
  73. data/lib/geokit/services/maxmind.rb +0 -39
  74. data/lib/geokit/services/openstreetmap.rb +0 -119
  75. data/lib/geokit/services/ripe.rb +0 -32
  76. data/lib/geokit/services/yandex.rb +0 -51
  77. data/test/test_google_geocoder3.rb +0 -238
  78. data/test/test_google_reverse_geocoder.rb +0 -49
@@ -0,0 +1,69 @@
1
+ module Geokit
2
+ module Geocoders
3
+ # Provides geocoding based upon an IP address. The underlying web service is a hostip.info
4
+ # which sources their data through a combination of publicly available information as well
5
+ # as community contributions.
6
+ class IpGeocoder < BaseIpGeocoder
7
+ private
8
+
9
+ # Given an IP address, returns a GeoLoc instance which contains latitude,
10
+ # longitude, city, and country code. Sets the success attribute to false if the ip
11
+ # parameter does not match an ip address.
12
+ def self.do_geocode(ip)
13
+ return GeoLoc.new unless valid_ip?(ip)
14
+ url = "http://api.hostip.info/get_html.php?ip=#{ip}&position=true"
15
+ res = call_geocoder_service(url)
16
+ ensure_utf8_encoding(res)
17
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
18
+ body = res.body
19
+ body = body.encode('UTF-8') if body.respond_to? :encode
20
+ parse :yaml, body
21
+ end
22
+
23
+ # Converts the body to YAML since its in the form of:
24
+ #
25
+ # Country: UNITED STATES (US)
26
+ # City: Sugar Grove, IL
27
+ # Latitude: 41.7696
28
+ # Longitude: -88.4588
29
+ #
30
+ # then instantiates a GeoLoc instance to populate with location data.
31
+ def self.parse_yaml(yaml) # :nodoc:
32
+ loc = GeoLoc.new
33
+ loc.provider = 'hostip'
34
+ loc.city, loc.state = yaml['City'].split(', ')
35
+ loc.country, loc.country_code = yaml['Country'].split(' (')
36
+ loc.lat = yaml['Latitude']
37
+ loc.lng = yaml['Longitude']
38
+ loc.country_code.chop!
39
+ loc.success = !(loc.city =~ /\(.+\)/)
40
+ loc
41
+ end
42
+
43
+ # Forces UTF-8 encoding on the body
44
+ # Rails expects string input to be UTF-8
45
+ # hostip.info specifies the charset encoding in the headers
46
+ # thus extract encoding from headers and tell Rails about it by forcing it
47
+ def self.ensure_utf8_encoding(res)
48
+ if (enc_string = extract_charset(res))
49
+ if defined?(Encoding) && Encoding.aliases.values.include?(enc_string.upcase)
50
+ res.body.force_encoding(enc_string.upcase) if res.body.respond_to?(:force_encoding)
51
+ res.body.encode("UTF-8")
52
+ else
53
+ require 'iconv'
54
+ res.body.replace Iconv.conv("UTF8", "iso88591", res.body)
55
+ end
56
+ end
57
+ end
58
+
59
+ # Extracts charset out of the response headers
60
+ def self.extract_charset(res)
61
+ if (content_type = res['content-type'])
62
+ capture = content_type.match(/charset=(.+)/)
63
+ capture && capture[1]
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,72 @@
1
+ module Geokit
2
+ module Geocoders
3
+ # MapQuest geocoder implementation. Requires the Geokit::Geocoders::mapquest variable to
4
+ # contain a MapQuest API key. Conforms to the interface set by the Geocoder class.
5
+ class MapQuestGeocoder < Geocoder
6
+
7
+ private
8
+
9
+ # Template method which does the reverse-geocode lookup.
10
+ def self.do_reverse_geocode(latlng)
11
+ latlng=LatLng.normalize(latlng)
12
+ url = "http://www.mapquestapi.com/geocoding/v1/reverse?key=#{Geokit::Geocoders::mapquest}&location=#{latlng.lat},#{latlng.lng}"
13
+ res = call_geocoder_service(url)
14
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
15
+ json = res.body
16
+ logger.debug "MapQuest reverse-geocoding. LL: #{latlng}. Result: #{json}"
17
+ parse :json, json, latlng
18
+ end
19
+
20
+ # Template method which does the geocode lookup.
21
+ def self.do_geocode(address)
22
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
23
+ url = "http://www.mapquestapi.com/geocoding/v1/address?key=#{Geokit::Geocoders::mapquest}&location=#{Geokit::Inflector::url_escape(address_str)}"
24
+ res = call_geocoder_service(url)
25
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
26
+ json = res.body
27
+ logger.debug "Mapquest geocoding. Address: #{address}. Result: #{json}"
28
+ parse :json, json
29
+ end
30
+
31
+ def self.parse_json(results)
32
+ return GeoLoc.new unless results['info']['statuscode'] == 0
33
+ loc = nil
34
+ results['results'].each do |result|
35
+ result['locations'].each do |location|
36
+ extracted_geoloc = extract_geoloc(location)
37
+ if loc.nil?
38
+ loc = extracted_geoloc
39
+ else
40
+ loc.all.push(extracted_geoloc)
41
+ end
42
+ end
43
+ end
44
+ loc
45
+ end
46
+
47
+ def self.extract_geoloc(result_json)
48
+ loc = GeoLoc.new
49
+ loc.lat = result_json['latLng']['lat']
50
+ loc.lng = result_json['latLng']['lng']
51
+ loc.provider = 'mapquest'
52
+ set_address_components(result_json, loc)
53
+ set_precision(result_json, loc)
54
+ loc.success = true
55
+ loc
56
+ end
57
+
58
+ def self.set_address_components(result_json, loc)
59
+ loc.country_code = result_json['adminArea1']
60
+ loc.street_address = result_json['street'].to_s.empty? ? nil : result_json['street']
61
+ loc.city = result_json['adminArea5']
62
+ loc.state = result_json['adminArea3']
63
+ loc.zip = result_json['postalCode']
64
+ end
65
+
66
+ def self.set_precision(result_json, loc)
67
+ loc.precision = result_json['geocodeQuality']
68
+ loc.accuracy = %w{unknown country state state city zip zip+4 street address building}.index(loc.precision)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ module Geokit
2
+ module Geocoders
3
+
4
+ @@geoip_data_path = 'DEFINE_THE_PATH_TO_GeoLiteCity.dat'
5
+ __define_accessors
6
+
7
+ # Provides geocoding based upon an IP address. The underlying web service is MaxMind
8
+ class MaxmindGeocoder < Geocoder
9
+ private
10
+
11
+ def self.do_geocode(ip)
12
+ res = GeoIP.new(Geokit::Geocoders::geoip_data_path).city(ip)
13
+
14
+ loc = GeoLoc.new(
15
+ :provider => 'maxmind_city',
16
+ :lat => res.latitude,
17
+ :lng => res.longitude,
18
+ :city => res.city_name,
19
+ :state => res.region_name,
20
+ :zip => res.postal_code,
21
+ :country_code => res.country_code2
22
+ )
23
+
24
+ loc.success = ( res.longitude.kind_of?(Numeric) && res.latitude.kind_of?(Numeric) )
25
+ loc
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,119 @@
1
+ module Geokit
2
+ module Geocoders
3
+ # Open Street Map geocoder implementation.
4
+ class OSMGeocoder < Geocoder
5
+
6
+ private
7
+
8
+ # Template method which does the geocode lookup.
9
+ def self.do_geocode(address, options = {})
10
+ options_str = generate_bool_param_for_option(:polygon, options)
11
+ options_str << generate_param_for_option(:json_callback, options)
12
+ options_str << generate_param_for_option(:countrycodes, options)
13
+ options_str << generate_param_for_option(:viewbox, options)
14
+
15
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
16
+
17
+ url = "http://nominatim.openstreetmap.org/search?format=json#{options_str}&addressdetails=1&q=#{Geokit::Inflector::url_escape(address_str)}"
18
+ res = call_geocoder_service(url)
19
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
20
+ json = res.body
21
+ logger.debug "OSM geocoding. Address: #{address}. Result: #{json}"
22
+ parse :json, json
23
+ end
24
+
25
+ def self.do_reverse_geocode(latlng, options = {})
26
+ latlng = LatLng.normalize(latlng)
27
+ options_str = generate_param_for(:lat, latlng.lat)
28
+ options_str << generate_param_for(:lon, latlng.lng)
29
+ options_str << generate_param_for_option(:zoom, options)
30
+ options_str << generate_param_for_option(:osm_type, options)
31
+ options_str << generate_param_for_option(:osm_id, options)
32
+ options_str << generate_param_for_option(:json_callback, options)
33
+ url = "http://nominatim.openstreetmap.org/reverse?format=json&addressdetails=1#{options_str}"
34
+ res = call_geocoder_service(url)
35
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
36
+ json = res.body
37
+ logger.debug "OSM reverse geocoding: Lat: #{latlng.lat}, Lng: #{latlng.lng}. Result: #{json}"
38
+ parse :json, json
39
+ end
40
+
41
+ def self.generate_param_for(param, value)
42
+ "&#{param}=#{Geokit::Inflector::url_escape(value.to_s)}"
43
+ end
44
+
45
+ def self.generate_param_for_option(param, options)
46
+ options[param] ? "&#{param}=#{Geokit::Inflector::url_escape(options[param])}" : ''
47
+ end
48
+
49
+ def self.generate_bool_param_for_option(param, options)
50
+ options[param] ? "&#{param}=1" : "&#{param}=0"
51
+ end
52
+
53
+ def self.parse_json(results)
54
+ if results.is_a?(Hash)
55
+ return GeoLoc.new if results['error']
56
+ results = [results]
57
+ end
58
+ return GeoLoc.new if results.empty?
59
+
60
+ loc = nil
61
+ results.each do |result|
62
+ extract_geoloc = extract_geoloc(result)
63
+ if loc.nil?
64
+ loc = extract_geoloc
65
+ else
66
+ loc.all.push(extract_geoloc)
67
+ end
68
+ end
69
+ loc
70
+ end
71
+
72
+ def self.extract_geoloc(result_json)
73
+ loc = GeoLoc.new
74
+
75
+ # basic
76
+ loc.lat = result_json['lat']
77
+ loc.lng = result_json['lon']
78
+
79
+ loc.provider = 'osm'
80
+
81
+ set_address_components(result_json['address'], loc)
82
+ set_precision(result_json, loc)
83
+ set_bounds(result_json['boundingbox'], loc)
84
+ loc.success = true
85
+
86
+ loc
87
+ end
88
+
89
+ def self.set_address_components(address_data, loc)
90
+ return unless address_data
91
+ loc.country = address_data['country']
92
+ loc.country_code = address_data['country_code'].upcase if address_data['country_code']
93
+ loc.state = address_data['state']
94
+ loc.city = address_data['city']
95
+ loc.city = address_data['county'] if loc.city.nil? && address_data['county']
96
+ loc.zip = address_data['postcode']
97
+ loc.district = address_data['city_district']
98
+ loc.district = address_data['state_district'] if loc.district.nil? && address_data['state_district']
99
+ loc.street_address = "#{address_data['road']} #{address_data['house_number']}".strip if address_data['road']
100
+ loc.street_name = address_data['road']
101
+ loc.street_number = address_data['house_number']
102
+ end
103
+
104
+ def self.set_precision(result_json, loc)
105
+ # Todo accuracy does not work as Yahoo and Google maps on OSM
106
+ #loc.accuracy = %w{unknown amenity building highway historic landuse leisure natural place railway shop tourism waterway man_made}.index(loc.precision)
107
+ loc.precision = result_json['class']
108
+ loc.accuracy = result_json['type']
109
+ end
110
+
111
+ def self.set_bounds(result_json, loc)
112
+ return unless result_json
113
+ loc.suggested_bounds = Bounds.normalize(
114
+ [result_json[0], result_json[1]],
115
+ [result_json[2], result_json[3]])
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,41 @@
1
+ module Geokit
2
+ module Geocoders
3
+ # Provides geocoding based upon an IP address. The underlying web service is geoplugin.net
4
+ class RipeGeocoder < BaseIpGeocoder
5
+ private
6
+
7
+ def self.do_geocode(ip)
8
+ return GeoLoc.new unless valid_ip?(ip)
9
+ url = "http://stat.ripe.net/data/geoloc/data.json?resource=#{ip}"
10
+ res = call_geocoder_service(url)
11
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
12
+ parse :json, res.body
13
+ end
14
+
15
+ def self.parse_json(json)
16
+ loc = GeoLoc.new
17
+ data = json['data']['locations'][0]
18
+
19
+ loc.provider='RIPE'
20
+ loc.lat = data['latitude']
21
+ loc.lng = data['longitude']
22
+ set_address_components(data, loc)
23
+ loc.success = (data['status_code'] == 200)
24
+ loc
25
+ end
26
+
27
+ def self.set_address_components(data, loc)
28
+ match = data['country'].match /([A-Z]+)(\(([A-Z]+)\))?/
29
+ if match[3]
30
+ loc.state = match[1]
31
+ loc.country_code = match[3]
32
+ else
33
+ loc.country_code = match[1]
34
+ end
35
+
36
+ loc.city = data['city']
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -6,7 +6,7 @@ module Geokit
6
6
  class UsGeocoder < Geocoder
7
7
 
8
8
  private
9
- def self.do_geocode(address, options = {})
9
+ def self.do_geocode(address)
10
10
  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
11
11
 
12
12
  query = (address_str =~ /^\d{5}(?:-\d{4})?$/ ? "zip" : "address") + "=#{Geokit::Inflector::url_escape(address_str)}"
@@ -17,34 +17,29 @@ module Geokit
17
17
  end
18
18
 
19
19
  url = "#{url}?#{query}"
20
- res = self.call_geocoder_service(url)
20
+ res = call_geocoder_service(url)
21
21
 
22
22
  return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
23
23
  data = res.body
24
24
  logger.debug "Geocoder.us geocoding. Address: #{address}. Result: #{data}"
25
+ parse_csv data
26
+ end
27
+
28
+ def self.parse_csv(data)
25
29
  array = data.chomp.split(',')
26
30
 
31
+ loc = GeoLoc.new
27
32
  if array.length == 5
28
- res=GeoLoc.new
29
- res.lat,res.lng,res.city,res.state,res.zip=array
30
- res.country_code='US'
31
- res.success=true
32
- return res
33
+ loc.lat,loc.lng,loc.city,loc.state,loc.zip=array
34
+ loc.country_code='US'
35
+ loc.success=true
33
36
  elsif array.length == 6
34
- res=GeoLoc.new
35
- res.lat,res.lng,res.street_address,res.city,res.state,res.zip=array
36
- res.country_code='US'
37
- res.success=true
38
- return res
39
- else
40
- logger.info "geocoder.us was unable to geocode address: "+address
41
- return GeoLoc.new
37
+ loc.lat,loc.lng,loc.street_address,loc.city,loc.state,loc.zip=array
38
+ loc.country_code='US'
39
+ loc.success=true
42
40
  end
43
- rescue
44
- logger.error "Caught an error during geocoder.us geocoding call: "+$!
45
- return GeoLoc.new
46
-
41
+ loc
47
42
  end
48
43
  end
49
- end
44
+ end
50
45
  end
@@ -5,79 +5,77 @@ module Geokit
5
5
  class YahooGeocoder < Geocoder
6
6
 
7
7
  private
8
- def self.submit_url(query_string)
8
+ def self.submit_url(address)
9
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
10
+ query_string = "?q=#{Geokit::Inflector::url_escape(address_str)}&flags=J"
11
+
9
12
  o = OauthUtil.new
10
13
  o.consumer_key = Geocoders::yahoo_consumer_key
11
14
  o.consumer_secret = Geocoders::yahoo_consumer_secret
12
15
  base = "http://yboss.yahooapis.com/geo/placefinder"
13
16
  parsed_url = URI.parse("#{base}#{query_string}")
14
- "http://yboss.yahooapis.com/geo/placefinder?#{o.sign(parsed_url).query_string}"
17
+ "#{base}?#{o.sign(parsed_url).query_string}"
15
18
  end
16
19
 
17
20
  # Template method which does the geocode lookup.
18
- def self.do_geocode(address, options = {})
19
- address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
20
- submit_url = submit_url("?q=#{Geokit::Inflector::url_escape(address_str)}&flags=J")
21
-
22
- res = self.call_geocoder_service(submit_url)
21
+ def self.do_geocode(address)
22
+ url = submit_url(address)
23
+ res = call_geocoder_service(url)
23
24
  return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
24
25
  json = res.body
25
26
  logger.debug "Yahoo geocoding. Address: #{address}. Result: #{json}"
26
- return self.json2GeoLoc(json, address)
27
+ parse :json, json
27
28
  end
28
29
 
29
- def self.json2GeoLoc(json, address)
30
- results = MultiJson.load(json)
31
-
32
- if results && results['bossresponse'] && results['bossresponse']['placefinder'] && results['bossresponse']['placefinder']['results'] && results['bossresponse']['placefinder']['results'].first != nil
33
- geoloc = nil
34
- results['bossresponse']['placefinder']['results'].each do |result|
35
- extracted_geoloc = extract_geoloc(result)
36
- if geoloc.nil?
37
- geoloc = extracted_geoloc
38
- else
39
- geoloc.all.push(extracted_geoloc)
40
- end
30
+ def self.parse_json(results)
31
+ boss_results = results && results['bossresponse'] && results['bossresponse']['placefinder'] && results['bossresponse']['placefinder']['results']
32
+ return GeoLoc.new unless boss_results && boss_results.first
33
+ loc = nil
34
+ boss_results.each do |result|
35
+ extracted_geoloc = extract_geoloc(result)
36
+ if loc.nil?
37
+ loc = extracted_geoloc
38
+ else
39
+ loc.all.push(extracted_geoloc)
41
40
  end
42
- return geoloc
43
- else
44
- logger.info "Yahoo was unable to geocode address: " + address
45
- return GeoLoc.new
46
41
  end
42
+ loc
47
43
  end
48
44
 
49
45
  def self.extract_geoloc(result_json)
50
- geoloc = GeoLoc.new
51
-
52
- # basic
53
- geoloc.lat = result_json['latitude']
54
- geoloc.lng = result_json['longitude']
55
- geoloc.country_code = result_json['countrycode']
56
- geoloc.provider = 'yahoo'
57
-
58
- # extended
59
- geoloc.street_address = result_json['line1'].to_s.empty? ? nil : result_json['line1']
60
- geoloc.city = result_json['city']
61
- geoloc.state = geoloc.is_us? ? result_json['statecode'] : result_json['state']
62
- geoloc.zip = result_json['postal']
46
+ loc = GeoLoc.new
47
+ loc.lat = result_json['latitude']
48
+ loc.lng = result_json['longitude']
49
+ loc.provider = 'yahoo'
50
+ set_address_components(result_json, loc)
51
+ set_precision(result_json, loc)
52
+ loc.success = true
53
+ loc
54
+ end
63
55
 
64
- geoloc.precision = case result_json['quality'].to_i
65
- when 9,10 then 'country'
66
- when 19..30 then 'state'
67
- when 39,40 then 'city'
68
- when 49,50 then 'neighborhood'
69
- when 59,60,64 then 'zip'
70
- when 74,75 then 'zip+4'
71
- when 70..72 then 'street'
72
- when 80..87 then 'address'
73
- when 62,63,90,99 then 'building'
74
- else 'unknown'
75
- end
56
+ def self.set_address_components(result_json, loc)
57
+ loc.country_code = result_json['countrycode']
58
+ loc.street_address = result_json['line1'].to_s.empty? ? nil : result_json['line1']
59
+ loc.city = result_json['city']
60
+ loc.state = loc.is_us? ? result_json['statecode'] : result_json['state']
61
+ loc.zip = result_json['postal']
62
+ end
76
63
 
77
- geoloc.accuracy = %w{unknown country state state city zip zip+4 street address building}.index(geoloc.precision)
78
- geoloc.success = true
64
+ def self.set_precision(result_json, loc)
65
+ loc.precision = case result_json['quality'].to_i
66
+ when 9,10 then 'country'
67
+ when 19..30 then 'state'
68
+ when 39,40 then 'city'
69
+ when 49,50 then 'neighborhood'
70
+ when 59,60,64 then 'zip'
71
+ when 74,75 then 'zip+4'
72
+ when 70..72 then 'street'
73
+ when 80..87 then 'address'
74
+ when 62,63,90,99 then 'building'
75
+ else 'unknown'
76
+ end
79
77
 
80
- return geoloc
78
+ loc.accuracy = %w{unknown country state state city zip zip+4 street address building}.index(loc.precision)
81
79
  end
82
80
  end
83
81
  end
@@ -118,9 +116,8 @@ class OauthUtil
118
116
  end
119
117
 
120
118
  def percent_encode( string )
121
-
122
119
  # ref http://snippets.dzone.com/posts/show/1260
123
- return URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A')
120
+ URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A')
124
121
  end
125
122
 
126
123
  # @ref http://oauth.net/core/1.0/#rfc.section.9.2
@@ -190,6 +187,6 @@ class OauthUtil
190
187
  # add signature
191
188
  @params[ 'oauth_signature' ] = signature
192
189
 
193
- return self
190
+ self
194
191
  end
195
192
  end