geokit 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.hound.yml +2 -0
  4. data/.rubocop.yml +358 -0
  5. data/.travis.yml +4 -4
  6. data/CHANGELOG.md +16 -0
  7. data/Gemfile +3 -3
  8. data/README.markdown +19 -4
  9. data/Rakefile +11 -16
  10. data/fixtures/keys.yml +9 -0
  11. data/fixtures/vcr_cassettes/google_postal_town.yml +117 -0
  12. data/fixtures/vcr_cassettes/mapbox_forward_geocode.yml +30 -30
  13. data/fixtures/vcr_cassettes/mapbox_forward_geocode_city_only.yml +25 -25
  14. data/fixtures/vcr_cassettes/mapbox_forward_geocode_state_only.yml +71 -0
  15. data/fixtures/vcr_cassettes/mapbox_reverse_geocode.yml +25 -25
  16. data/fixtures/vcr_cassettes/test_component_filtering_off.yml +390 -0
  17. data/fixtures/vcr_cassettes/test_component_filtering_on.yml +164 -0
  18. data/fixtures/vcr_cassettes/test_component_filtering_on_without_filter.yml +404 -0
  19. data/geokit.gemspec +24 -23
  20. data/lib/geokit.rb +7 -7
  21. data/lib/geokit/core_ext.rb +1 -1
  22. data/lib/geokit/geo_loc.rb +25 -19
  23. data/lib/geokit/geocoders.rb +21 -30
  24. data/lib/geokit/geocoders/bing.rb +5 -4
  25. data/lib/geokit/geocoders/ca_geocoder.rb +10 -11
  26. data/lib/geokit/geocoders/fcc.rb +9 -9
  27. data/lib/geokit/geocoders/free_geo_ip.rb +8 -8
  28. data/lib/geokit/geocoders/geo_plugin.rb +7 -7
  29. data/lib/geokit/geocoders/geobytes.rb +10 -10
  30. data/lib/geokit/geocoders/geocodio.rb +14 -14
  31. data/lib/geokit/geocoders/geonames.rb +12 -12
  32. data/lib/geokit/geocoders/google.rb +89 -61
  33. data/lib/geokit/geocoders/ip.rb +9 -14
  34. data/lib/geokit/geocoders/mapbox.rb +30 -30
  35. data/lib/geokit/geocoders/mapquest.rb +12 -12
  36. data/lib/geokit/geocoders/maxmind.rb +1 -1
  37. data/lib/geokit/geocoders/opencage.rb +19 -19
  38. data/lib/geokit/geocoders/openstreetmap.rb +21 -19
  39. data/lib/geokit/geocoders/ripe.rb +7 -7
  40. data/lib/geokit/geocoders/us_geocoder.rb +5 -5
  41. data/lib/geokit/geocoders/yahoo.rb +46 -46
  42. data/lib/geokit/geocoders/yandex.rb +18 -17
  43. data/lib/geokit/inflectors.rb +5 -5
  44. data/lib/geokit/lat_lng.rb +5 -4
  45. data/lib/geokit/multi_geocoder.rb +4 -2
  46. data/lib/geokit/net_adapter/net_http.rb +3 -2
  47. data/lib/geokit/net_adapter/typhoeus.rb +2 -1
  48. data/lib/geokit/version.rb +1 -1
  49. data/test/coverage_loader.rb +25 -0
  50. data/test/helper.rb +18 -87
  51. data/test/test_base_geocoder.rb +44 -11
  52. data/test/test_bing_geocoder.rb +40 -48
  53. data/test/test_bounds.rb +1 -1
  54. data/test/test_ca_geocoder.rb +15 -15
  55. data/test/test_fcc_geocoder.rb +8 -9
  56. data/test/test_free_geo_ip_geocoder.rb +8 -10
  57. data/test/test_geo_plugin_geocoder.rb +21 -22
  58. data/test/test_geobytes_geocoder.rb +9 -11
  59. data/test/test_geocodio_geocoder.rb +12 -14
  60. data/test/test_geoloc.rb +48 -49
  61. data/test/test_geonames_geocoder.rb +19 -23
  62. data/test/test_google_geocoder.rb +197 -189
  63. data/test/test_inflector.rb +7 -7
  64. data/test/test_ipgeocoder.rb +32 -31
  65. data/test/test_latlng.rb +28 -28
  66. data/test/test_map_quest.rb +23 -27
  67. data/test/test_mapbox_geocoder.rb +38 -28
  68. data/test/test_mappable.rb +2 -2
  69. data/test/test_maxmind_geocoder.rb +16 -16
  70. data/test/test_multi_geocoder.rb +5 -5
  71. data/test/test_multi_ip_geocoder.rb +3 -3
  72. data/test/test_net_adapter.rb +4 -4
  73. data/test/test_opencage_geocoder.rb +58 -67
  74. data/test/test_openstreetmap_geocoder.rb +67 -65
  75. data/test/test_polygon.rb +4 -22
  76. data/test/test_ripe_geocoder.rb +21 -26
  77. data/test/test_us_geocoder.rb +21 -21
  78. data/test/test_useragent.rb +46 -0
  79. data/test/test_yahoo_geocoder.rb +35 -47
  80. data/test/test_yandex_geocoder.rb +29 -27
  81. data/test/vcr_loader.rb +18 -0
  82. metadata +20 -6
@@ -8,18 +8,18 @@ module Geokit
8
8
  private
9
9
 
10
10
  # Template method which does the geocode lookup.
11
- def self.do_geocode(address)
11
+ def self.do_geocode(address, _=nil)
12
12
  process :xml, submit_url(address)
13
13
  end
14
14
 
15
15
  def self.submit_url(address)
16
16
  if key.nil? || key.empty?
17
- raise(Geokit::Geocoders::GeocodeError, "Geonames requires a key to use their service.")
17
+ raise(Geokit::Geocoders::GeocodeError, 'Geonames requires a key to use their service.')
18
18
  end
19
19
 
20
20
  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
21
21
  # geonames need a space seperated search string
22
- address_str.gsub!(/,/, " ")
22
+ address_str.gsub!(/,/, ' ')
23
23
  params = "/postalCodeSearch?placename=#{Geokit::Inflector.url_escape(address_str)}&maxRows=10"
24
24
 
25
25
  if premium
@@ -30,21 +30,21 @@ module Geokit
30
30
  end
31
31
 
32
32
  XML_MAPPINGS = {
33
- city: "name",
34
- state_name: "adminName1",
35
- state_code: "adminCode1",
36
- zip: "postalcode",
37
- country_code: "countryCode",
38
- lat: "lat",
39
- lng: "lng",
33
+ city: 'name',
34
+ state_name: 'adminName1',
35
+ state_code: 'adminCode1',
36
+ zip: 'postalcode',
37
+ country_code: 'countryCode',
38
+ lat: 'lat',
39
+ lng: 'lng',
40
40
  }
41
41
 
42
42
  def self.parse_xml(xml)
43
- count = xml.elements["geonames/totalResultsCount"]
43
+ count = xml.elements['geonames/totalResultsCount']
44
44
  return GeoLoc.new unless !count.nil? && count.text.to_i > 0
45
45
  loc = new_loc
46
46
  # only take the first result
47
- set_mappings(loc, xml.elements["geonames/code"], XML_MAPPINGS)
47
+ set_mappings(loc, xml.elements['geonames/code'], XML_MAPPINGS)
48
48
  loc.success = true
49
49
  loc
50
50
  end
@@ -8,9 +8,18 @@ module Geokit
8
8
 
9
9
  # ==== OPTIONS
10
10
  # * :language - See: https://developers.google.com/maps/documentation/geocoding
11
+ # * :result_type - This option allows restricting results by specific result types.
12
+ # See https://developers.google.com/maps/documentation/geocoding/intro#reverse-restricted
13
+ # Note: This parameter is available only for requests that include an API key or a client ID.
14
+ # * :location_type - This option allows restricting results by specific location type.
15
+ # See https://developers.google.com/maps/documentation/geocoding/intro#reverse-restricted
16
+ # Note: This parameter is available only for requests that include an API key or a client ID.
11
17
  def self.do_reverse_geocode(latlng, options = {})
12
18
  latlng = LatLng.normalize(latlng)
13
- url = submit_url("latlng=#{Geokit::Inflector.url_escape(latlng.ll)}", options)
19
+ latlng_str = "latlng=#{Geokit::Inflector.url_escape(latlng.ll)}"
20
+ result_type_str = options[:result_type] ? "&result_type=#{options[:result_type]}" : ''
21
+ location_type_str = options[:location_type] ? "&location_type=#{options[:location_type]}" : ''
22
+ url = submit_url("#{latlng_str}#{result_type_str}#{location_type_str}", options)
14
23
  process :json, url
15
24
  end
16
25
 
@@ -24,6 +33,9 @@ module Geokit
24
33
  #
25
34
  # If you'd like the Google Geocoder to prefer results within a given viewport,
26
35
  # you can pass a Geokit::Bounds object as the :bias value.
36
+ # * :components - This option allows restricting results by specific areas. See
37
+ # https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering
38
+ # for details.
27
39
  #
28
40
  # ==== EXAMPLES
29
41
  # # By default, the geocoder will return Toledo, OH
@@ -36,31 +48,40 @@ module Geokit
36
48
  # # When biased to an bounding box around California, it will now return the Winnetka neighbourhood, CA
37
49
  # bounds = Geokit::Bounds.normalize([34.074081, -118.694401], [34.321129, -118.399487])
38
50
  # Geokit::Geocoders::GoogleGeocoder.geocode('Winnetka', :bias => bounds).state # => 'CA'
51
+ #
52
+ # # By default, the geocoder will return several matches for Austin with
53
+ # the first one being in Texas
54
+ # Geokit::Geocoders::GoogleGeocoder.geocode('Austin').state # => 'TX'
55
+ # # Using Component Filtering the results can be restricted to a specific
56
+ # area, e.g. IL
57
+ # Geokit::Geocoders::GoogleGeocoder.geocode('Austin',
58
+ # :components => {administrative_area: 'IL', country: 'US'}).state # => 'IL'
39
59
  def self.do_geocode(address, options = {})
40
- bias_str = options[:bias] ? construct_bias_string_from_options(options[:bias]) : ""
60
+ bias_str = options[:bias] ? construct_bias_string_from_options(options[:bias]) : ''
61
+ components_str = options[:components] ? construct_components_string_from_options(options[:components]) : ''
41
62
  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
42
- url = submit_url("address=#{Geokit::Inflector.url_escape(address_str)}#{bias_str}", options)
63
+ url = submit_url("address=#{Geokit::Inflector.url_escape(address_str)}#{bias_str}#{components_str}", options)
43
64
  process :json, url
44
65
  end
45
66
 
46
67
  # This code comes from Googles Examples
47
68
  # http://gmaps-samples.googlecode.com/svn/trunk/urlsigning/urlsigner.rb
48
69
  def self.sign_gmap_bus_api_url(urlToSign, google_cryptographic_key)
49
- require "base64"
50
- require "openssl"
70
+ require 'base64'
71
+ require 'openssl'
51
72
  # Decode the private key
52
- rawKey = Base64.decode64(google_cryptographic_key.tr("-_", "+/"))
73
+ rawKey = Base64.decode64(google_cryptographic_key.tr('-_', '+/'))
53
74
  # create a signature using the private key and the URL
54
- rawSignature = OpenSSL::HMAC.digest("sha1", rawKey, urlToSign)
75
+ rawSignature = OpenSSL::HMAC.digest('sha1', rawKey, urlToSign)
55
76
  # encode the signature into base64 for url use form.
56
- Base64.encode64(rawSignature).tr("+/", "-_").gsub(/\n/, "")
77
+ Base64.encode64(rawSignature).tr('+/', '-_').gsub(/\n/, '')
57
78
  end
58
79
 
59
80
  def self.submit_url(query_string, options = {})
60
- language_str = options[:language] ? "&language=#{options[:language]}" : ""
81
+ language_str = options[:language] ? "&language=#{options[:language]}" : ''
61
82
  query_string = "/maps/api/geocode/json?sensor=false&#{query_string}#{language_str}"
62
83
  if client_id && cryptographic_key
63
- channel_string = channel ? "&channel=#{channel}" : ""
84
+ channel_string = channel ? "&channel=#{channel}" : ''
64
85
  urlToSign = query_string + "&client=#{client_id}" + channel_string
65
86
  signature = sign_gmap_bus_api_url(urlToSign, cryptographic_key)
66
87
  "#{protocol}://maps.googleapis.com" + urlToSign + "&signature=#{signature}"
@@ -84,21 +105,27 @@ module Geokit
84
105
  end
85
106
  end
86
107
 
108
+ def self.construct_components_string_from_options(components={})
109
+ unless components.empty?
110
+ "&components=#{components.to_a.map { |pair| pair.join(':').downcase }.join(CGI.escape('|'))}"
111
+ end
112
+ end
113
+
87
114
  def self.parse_json(results)
88
- case results["status"]
89
- when "OVER_QUERY_LIMIT"
90
- raise Geokit::Geocoders::TooManyQueriesError, results["error_message"]
91
- when "REQUEST_DENIED"
92
- raise Geokit::Geocoders::AccessDeniedError, results["error_message"]
93
- when "ZERO_RESULTS"
115
+ case results['status']
116
+ when 'OVER_QUERY_LIMIT'
117
+ raise Geokit::Geocoders::TooManyQueriesError, results['error_message']
118
+ when 'REQUEST_DENIED'
119
+ raise Geokit::Geocoders::AccessDeniedError, results['error_message']
120
+ when 'ZERO_RESULTS'
94
121
  return GeoLoc.new
95
- when "OK"
122
+ when 'OK'
96
123
  # all good
97
124
  else
98
- raise Geokit::Geocoders::GeocodeError, results["error_message"]
125
+ raise Geokit::Geocoders::GeocodeError, results['error_message']
99
126
  end
100
127
 
101
- unsorted = results["results"].map do |addr|
128
+ unsorted = results['results'].map do |addr|
102
129
  single_json_to_geoloc(addr)
103
130
  end
104
131
 
@@ -125,10 +152,10 @@ module Geokit
125
152
  # these do not map well. Perhaps we should guess better based on size
126
153
  # of bounding box where it exists? Does it really matter?
127
154
  ACCURACY = {
128
- "ROOFTOP" => 9,
129
- "RANGE_INTERPOLATED" => 8,
130
- "GEOMETRIC_CENTER" => 5,
131
- "APPROXIMATE" => 4,
155
+ 'ROOFTOP' => 9,
156
+ 'RANGE_INTERPOLATED' => 8,
157
+ 'GEOMETRIC_CENTER' => 5,
158
+ 'APPROXIMATE' => 4,
132
159
  }
133
160
 
134
161
  PRECISIONS = %w(unknown country state state city zip zip+4 street address building)
@@ -136,17 +163,17 @@ module Geokit
136
163
  def self.single_json_to_geoloc(addr)
137
164
  loc = new_loc
138
165
  loc.success = true
139
- loc.full_address = addr["formatted_address"]
166
+ loc.full_address = addr['formatted_address']
140
167
 
141
168
  set_address_components(loc, addr)
142
169
  set_precision(loc, addr)
143
170
  if loc.street_name
144
- loc.street_address = [loc.street_number, loc.street_name].join(" ").strip
171
+ loc.street_address = [loc.street_number, loc.street_name].join(' ').strip
145
172
  end
146
173
 
147
- ll = addr["geometry"]["location"]
148
- loc.lat = ll["lat"].to_f
149
- loc.lng = ll["lng"].to_f
174
+ ll = addr['geometry']['location']
175
+ loc.lat = ll['lat'].to_f
176
+ loc.lng = ll['lng'].to_f
150
177
 
151
178
  set_bounds(loc, addr)
152
179
 
@@ -157,59 +184,60 @@ module Geokit
157
184
  end
158
185
 
159
186
  def self.set_bounds(loc, addr)
160
- viewport = addr["geometry"]["viewport"]
161
- ne = Geokit::LatLng.from_json(viewport["northeast"])
162
- sw = Geokit::LatLng.from_json(viewport["southwest"])
187
+ viewport = addr['geometry']['viewport']
188
+ ne = Geokit::LatLng.from_json(viewport['northeast'])
189
+ sw = Geokit::LatLng.from_json(viewport['southwest'])
163
190
  loc.suggested_bounds = Geokit::Bounds.new(sw, ne)
164
191
  end
165
192
 
166
193
  def self.set_address_components(loc, addr)
167
- addr["address_components"].each do |comp|
168
- types = comp["types"]
194
+ addr['address_components'].each do |comp|
195
+ types = comp['types']
169
196
  case
170
- when types.include?("subpremise")
171
- loc.sub_premise = comp["short_name"]
172
- when types.include?("street_number")
173
- loc.street_number = comp["short_name"]
174
- when types.include?("route")
175
- loc.street_name = comp["long_name"]
176
- when types.include?("locality")
177
- loc.city = comp["long_name"]
178
- when types.include?("administrative_area_level_1")
179
- loc.state_code = comp["short_name"]
180
- loc.state_name = comp["long_name"]
181
- loc.province = comp["short_name"]
182
- when types.include?("postal_code")
183
- loc.zip = comp["long_name"]
184
- when types.include?("country")
185
- loc.country_code = comp["short_name"]
186
- loc.country = comp["long_name"]
187
- when types.include?("administrative_area_level_2")
188
- loc.district = comp["long_name"]
189
- when types.include?("neighborhood")
190
- loc.neighborhood = comp["short_name"]
197
+ when types.include?('subpremise')
198
+ loc.sub_premise = comp['short_name']
199
+ when types.include?('street_number')
200
+ loc.street_number = comp['short_name']
201
+ when types.include?('route')
202
+ loc.street_name = comp['long_name']
203
+ when types.include?('locality')
204
+ loc.city = comp['long_name']
205
+ when types.include?('administrative_area_level_1') # state
206
+ loc.state_code = comp['short_name']
207
+ loc.state_name = comp['long_name']
208
+ when types.include?('postal_town')
209
+ loc.city = comp['long_name']
210
+ when types.include?('postal_code')
211
+ loc.zip = comp['long_name']
212
+ when types.include?('country')
213
+ loc.country_code = comp['short_name']
214
+ loc.country = comp['long_name']
215
+ when types.include?('administrative_area_level_2')
216
+ loc.district = comp['long_name']
217
+ when types.include?('neighborhood')
218
+ loc.neighborhood = comp['short_name']
191
219
  # Use either sublocality or admin area level 3 if google does not return a city
192
- when types.include?("sublocality")
193
- loc.city = comp["long_name"] if loc.city.nil?
194
- when types.include?("administrative_area_level_3")
195
- loc.city = comp["long_name"] if loc.city.nil?
220
+ when types.include?('sublocality')
221
+ loc.city = comp['long_name'] if loc.city.nil?
222
+ when types.include?('administrative_area_level_3')
223
+ loc.city = comp['long_name'] if loc.city.nil?
196
224
  end
197
225
  end
198
226
  end
199
227
 
200
228
  def self.set_precision(loc, addr)
201
- loc.accuracy = ACCURACY[addr["geometry"]["location_type"]]
229
+ loc.accuracy = ACCURACY[addr['geometry']['location_type']]
202
230
  loc.precision = PRECISIONS[loc.accuracy]
203
231
  # try a few overrides where we can
204
232
  if loc.sub_premise
205
233
  loc.precision = PRECISIONS[9]
206
234
  loc.accuracy = 9
207
235
  end
208
- if loc.street_name && loc.precision == "city"
236
+ if loc.street_name && loc.precision == 'city'
209
237
  loc.precision = PRECISIONS[7]
210
238
  loc.accuracy = 7
211
239
  end
212
- if addr["types"].include?("postal_code")
240
+ if addr['types'].include?('postal_code')
213
241
  loc.precision = PRECISIONS[6]
214
242
  loc.accuracy = 6
215
243
  end
@@ -9,14 +9,14 @@ module Geokit
9
9
  # Given an IP address, returns a GeoLoc instance which contains latitude,
10
10
  # longitude, city, and country code. Sets the success attribute to false if the ip
11
11
  # parameter does not match an ip address.
12
- def self.do_geocode(ip)
12
+ def self.do_geocode(ip, _=nil)
13
13
  return GeoLoc.new unless valid_ip?(ip)
14
14
  url = submit_url(ip)
15
15
  res = call_geocoder_service(url)
16
16
  return GeoLoc.new unless net_adapter.success?(res)
17
17
  ensure_utf8_encoding(res)
18
18
  body = res.body
19
- body = body.encode("UTF-8") if body.respond_to? :encode
19
+ body = body.encode('UTF-8') if body.respond_to? :encode
20
20
  parse :yaml, body
21
21
  end
22
22
 
@@ -34,10 +34,10 @@ module Geokit
34
34
  # then instantiates a GeoLoc instance to populate with location data.
35
35
  def self.parse_yaml(yaml) # :nodoc:
36
36
  loc = new_loc
37
- loc.city, loc.state_code = yaml["City"].split(", ")
38
- loc.country, loc.country_code = yaml["Country"].split(" (")
39
- loc.lat = yaml["Latitude"]
40
- loc.lng = yaml["Longitude"]
37
+ loc.city, loc.state_code = yaml['City'].split(', ')
38
+ loc.country, loc.country_code = yaml['Country'].split(' (')
39
+ loc.lat = yaml['Latitude']
40
+ loc.lng = yaml['Longitude']
41
41
  loc.country_code.chop!
42
42
  loc.success = !(loc.city =~ /\(.+\)/)
43
43
  loc
@@ -49,19 +49,14 @@ module Geokit
49
49
  # thus extract encoding from headers and tell Rails about it by forcing it
50
50
  def self.ensure_utf8_encoding(res)
51
51
  if (enc_string = extract_charset(res))
52
- if defined?(Encoding) && Encoding.aliases.values.include?(enc_string.upcase)
53
- res.body.force_encoding(enc_string.upcase) if res.body.respond_to?(:force_encoding)
54
- res.body.encode("UTF-8")
55
- else
56
- require "iconv"
57
- res.body.replace Iconv.conv("UTF8", "iso88591", res.body)
58
- end
52
+ res.body.force_encoding(enc_string.upcase) if res.body.respond_to?(:force_encoding)
53
+ res.body.encode('UTF-8')
59
54
  end
60
55
  end
61
56
 
62
57
  # Extracts charset out of the response headers
63
58
  def self.extract_charset(res)
64
- if (content_type = res["content-type"])
59
+ if (content_type = res['content-type'])
65
60
  capture = content_type.match(/charset=(.+)/)
66
61
  capture && capture[1]
67
62
  end
@@ -9,7 +9,7 @@ module Geokit
9
9
  private
10
10
 
11
11
  # Template method which does the reverse-geocode lookup.
12
- def self.do_reverse_geocode(latlng, options = {})
12
+ def self.do_reverse_geocode(latlng, _options = nil)
13
13
  latlng = LatLng.normalize(latlng)
14
14
  url = "#{protocol}://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/"
15
15
  url += "#{latlng.lng},#{latlng.lat}.json?access_token=#{key}"
@@ -17,7 +17,7 @@ module Geokit
17
17
  end
18
18
 
19
19
  # Template method which does the geocode lookup.
20
- def self.do_geocode(address, options = {})
20
+ def self.do_geocode(address, _options = nil)
21
21
  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
22
22
  url = "#{protocol}://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/"
23
23
  url += "#{Geokit::Inflector.url_escape(address_str)}.json?access_token=#{key}"
@@ -25,9 +25,9 @@ module Geokit
25
25
  end
26
26
 
27
27
  def self.parse_json(results)
28
- return GeoLoc.new unless results["features"].count > 0
28
+ return GeoLoc.new unless results['features'].count > 0
29
29
  loc = nil
30
- results["features"].each do |feature|
30
+ results['features'].each do |feature|
31
31
  extracted_geoloc = extract_geoloc(feature)
32
32
  if loc.nil?
33
33
  loc = extracted_geoloc
@@ -40,52 +40,52 @@ module Geokit
40
40
 
41
41
  def self.extract_geoloc(result_json)
42
42
  loc = new_loc
43
- loc.lng = result_json["center"][0]
44
- loc.lat = result_json["center"][1]
43
+ loc.lng = result_json['center'][0]
44
+ loc.lat = result_json['center'][1]
45
45
  set_address_components(result_json, loc)
46
46
  set_precision(loc)
47
- set_bounds(result_json["bbox"], loc)
47
+ set_bounds(result_json['bbox'], loc)
48
48
  loc.success = true
49
49
  loc
50
50
  end
51
51
 
52
52
  def self.set_address_components(result_json, loc)
53
- if result_json["context"]
54
- result_json["context"].each do |context|
55
- if context["id"] =~ /^country\./
56
- loc.country = context["text"]
57
- elsif context["id"] =~ /^province\./
58
- loc.state = context["text"]
59
- elsif context["id"] =~ /^city\./
60
- loc.city = context["text"]
61
- elsif context["id"] =~ /^postcode/
62
- loc.zip = context["text"]
53
+ if result_json['context']
54
+ result_json['context'].each do |context|
55
+ if context['id'] =~ /^country\./
56
+ loc.country = context['text']
57
+ elsif context['id'] =~ /^province\./
58
+ loc.state = context['text']
59
+ elsif context['id'] =~ /^city\./
60
+ loc.city = context['text']
61
+ elsif context['id'] =~ /^postcode/
62
+ loc.zip = context['text']
63
63
  end
64
64
  end
65
65
  loc.country = loc.country_code if loc.country_code && !loc.country
66
66
  end
67
- if result_json["place_name"]
68
- loc.full_address = result_json["place_name"]
67
+ if result_json['place_name']
68
+ loc.full_address = result_json['place_name']
69
69
  end
70
- if !loc.city && result_json["id"] =~ /^city\./
71
- loc.city = result_json["text"]
70
+ if !loc.city && result_json['id'] =~ /^city\./
71
+ loc.city = result_json['text']
72
+ end
73
+ if !loc.state && result_json['id'] =~ /^province\./
74
+ loc.state = result_json['text']
72
75
  end
73
76
  end
74
77
 
75
- PRECISION_VALUES = %w(unknown country state city zip full_address)
78
+ PRECISION_VALUES = %w(country state city zip)
76
79
 
77
80
  def self.set_precision(loc)
78
- (1...PRECISION_VALUES.length - 1).each do |i|
79
- if loc.send(PRECISION_VALUES[i]) && loc.send(PRECISION_VALUES[i]).length
80
- loc.precision = PRECISION_VALUES[i]
81
- else
82
- break
83
- end
81
+ PRECISION_VALUES.each do |precision|
82
+ break unless loc.send(precision) && loc.send(precision).length
83
+ loc.precision = precision
84
84
  end
85
85
  end
86
86
 
87
- def self.set_bounds(result_json, loc)
88
- if bounds = result_json
87
+ def self.set_bounds(bounds, loc)
88
+ if bounds
89
89
  loc.suggested_bounds = Bounds.normalize([bounds[1], bounds[0]], [bounds[3], bounds[2]])
90
90
  end
91
91
  end