geocoder 1.2.6 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +189 -1
  3. data/LICENSE +1 -1
  4. data/README.md +387 -755
  5. data/examples/autoexpire_cache_redis.rb +5 -3
  6. data/examples/reverse_geocode_job.rb +40 -0
  7. data/lib/generators/geocoder/config/templates/initializer.rb +17 -16
  8. data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +2 -0
  9. data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +2 -0
  10. data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +1 -1
  11. data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +1 -1
  12. data/lib/generators/geocoder/migration_version.rb +15 -0
  13. data/lib/geocoder/cache.rb +6 -2
  14. data/lib/geocoder/calculations.rb +30 -38
  15. data/lib/geocoder/cli.rb +2 -2
  16. data/lib/geocoder/configuration.rb +18 -5
  17. data/lib/geocoder/esri_token.rb +38 -0
  18. data/lib/geocoder/exceptions.rb +19 -0
  19. data/lib/geocoder/ip_address.rb +16 -11
  20. data/lib/geocoder/kernel_logger.rb +25 -0
  21. data/lib/geocoder/logger.rb +47 -0
  22. data/lib/geocoder/lookup.rb +31 -12
  23. data/lib/geocoder/lookups/amap.rb +63 -0
  24. data/lib/geocoder/lookups/baidu.rb +17 -9
  25. data/lib/geocoder/lookups/baidu_ip.rb +7 -31
  26. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
  27. data/lib/geocoder/lookups/base.rb +73 -25
  28. data/lib/geocoder/lookups/bing.rb +38 -15
  29. data/lib/geocoder/lookups/db_ip_com.rb +52 -0
  30. data/lib/geocoder/lookups/dstk.rb +4 -2
  31. data/lib/geocoder/lookups/esri.rb +55 -8
  32. data/lib/geocoder/lookups/freegeoip.rb +18 -5
  33. data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
  34. data/lib/geocoder/lookups/geocodio.rb +8 -8
  35. data/lib/geocoder/lookups/geoip2.rb +10 -5
  36. data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
  37. data/lib/geocoder/lookups/google.rb +37 -9
  38. data/lib/geocoder/lookups/google_places_details.rb +9 -9
  39. data/lib/geocoder/lookups/google_places_search.rb +33 -0
  40. data/lib/geocoder/lookups/google_premier.rb +11 -1
  41. data/lib/geocoder/lookups/here.rb +29 -23
  42. data/lib/geocoder/lookups/ip2location.rb +67 -0
  43. data/lib/geocoder/lookups/ipapi_com.rb +82 -0
  44. data/lib/geocoder/lookups/ipdata_co.rb +62 -0
  45. data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
  46. data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
  47. data/lib/geocoder/lookups/ipregistry.rb +68 -0
  48. data/lib/geocoder/lookups/ipstack.rb +63 -0
  49. data/lib/geocoder/lookups/latlon.rb +59 -0
  50. data/lib/geocoder/lookups/location_iq.rb +50 -0
  51. data/lib/geocoder/lookups/mapbox.rb +59 -0
  52. data/lib/geocoder/lookups/mapquest.rb +7 -9
  53. data/lib/geocoder/lookups/maxmind.rb +7 -7
  54. data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
  55. data/lib/geocoder/lookups/maxmind_local.rb +9 -2
  56. data/lib/geocoder/lookups/nominatim.rb +18 -6
  57. data/lib/geocoder/lookups/opencagedata.rb +16 -9
  58. data/lib/geocoder/lookups/osmnames.rb +57 -0
  59. data/lib/geocoder/lookups/pelias.rb +63 -0
  60. data/lib/geocoder/lookups/pickpoint.rb +41 -0
  61. data/lib/geocoder/lookups/pointpin.rb +14 -13
  62. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +7 -8
  63. data/lib/geocoder/lookups/postcodes_io.rb +31 -0
  64. data/lib/geocoder/lookups/smarty_streets.rb +23 -5
  65. data/lib/geocoder/lookups/telize.rb +42 -7
  66. data/lib/geocoder/lookups/tencent.rb +59 -0
  67. data/lib/geocoder/lookups/yandex.rb +17 -9
  68. data/lib/geocoder/models/active_record.rb +4 -3
  69. data/lib/geocoder/models/mongo_base.rb +0 -2
  70. data/lib/geocoder/query.rb +15 -1
  71. data/lib/geocoder/railtie.rb +1 -1
  72. data/lib/geocoder/request.rb +103 -14
  73. data/lib/geocoder/results/amap.rb +87 -0
  74. data/lib/geocoder/results/baidu.rb +10 -14
  75. data/lib/geocoder/results/ban_data_gouv_fr.rb +257 -0
  76. data/lib/geocoder/results/base.rb +13 -1
  77. data/lib/geocoder/results/bing.rb +5 -1
  78. data/lib/geocoder/results/db_ip_com.rb +58 -0
  79. data/lib/geocoder/results/esri.rb +30 -6
  80. data/lib/geocoder/results/freegeoip.rb +2 -7
  81. data/lib/geocoder/results/geocoder_ca.rb +3 -3
  82. data/lib/geocoder/results/geocodio.rb +15 -3
  83. data/lib/geocoder/results/geoip2.rb +37 -25
  84. data/lib/geocoder/results/geoportail_lu.rb +71 -0
  85. data/lib/geocoder/results/google.rb +26 -0
  86. data/lib/geocoder/results/google_places_details.rb +4 -0
  87. data/lib/geocoder/results/google_places_search.rb +52 -0
  88. data/lib/geocoder/results/here.rb +21 -1
  89. data/lib/geocoder/results/ip2location.rb +22 -0
  90. data/lib/geocoder/results/ipapi_com.rb +45 -0
  91. data/lib/geocoder/results/ipdata_co.rb +40 -0
  92. data/lib/geocoder/results/ipgeolocation.rb +59 -0
  93. data/lib/geocoder/results/ipinfo_io.rb +48 -0
  94. data/lib/geocoder/results/ipregistry.rb +308 -0
  95. data/lib/geocoder/results/ipstack.rb +60 -0
  96. data/lib/geocoder/results/latlon.rb +71 -0
  97. data/lib/geocoder/results/location_iq.rb +6 -0
  98. data/lib/geocoder/results/mapbox.rb +57 -0
  99. data/lib/geocoder/results/mapquest.rb +5 -8
  100. data/lib/geocoder/results/maxmind.rb +0 -5
  101. data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
  102. data/lib/geocoder/results/maxmind_local.rb +0 -5
  103. data/lib/geocoder/results/nominatim.rb +18 -3
  104. data/lib/geocoder/results/opencagedata.rb +20 -2
  105. data/lib/geocoder/results/osmnames.rb +56 -0
  106. data/lib/geocoder/results/pelias.rb +58 -0
  107. data/lib/geocoder/results/pickpoint.rb +6 -0
  108. data/lib/geocoder/results/pointpin.rb +0 -4
  109. data/lib/geocoder/results/postcodes_io.rb +40 -0
  110. data/lib/geocoder/results/smarty_streets.rb +55 -19
  111. data/lib/geocoder/results/telize.rb +0 -5
  112. data/lib/geocoder/results/tencent.rb +72 -0
  113. data/lib/geocoder/results/test.rb +1 -1
  114. data/lib/geocoder/results/yandex.rb +57 -7
  115. data/lib/geocoder/sql.rb +9 -6
  116. data/lib/geocoder/stores/active_record.rb +49 -10
  117. data/lib/geocoder/stores/base.rb +2 -14
  118. data/lib/geocoder/stores/mongo_base.rb +0 -31
  119. data/lib/geocoder/version.rb +1 -1
  120. data/lib/geocoder.rb +2 -1
  121. data/lib/hash_recursive_merge.rb +1 -2
  122. data/lib/maxmind_database.rb +4 -4
  123. data/lib/tasks/geocoder.rake +29 -4
  124. metadata +56 -159
  125. data/.gitignore +0 -6
  126. data/.travis.yml +0 -31
  127. data/Rakefile +0 -25
  128. data/gemfiles/Gemfile.mongoid-2.4.x +0 -16
  129. data/lib/geocoder/lookups/geocoder_us.rb +0 -39
  130. data/lib/geocoder/lookups/okf.rb +0 -43
  131. data/lib/geocoder/lookups/ovi.rb +0 -62
  132. data/lib/geocoder/lookups/yahoo.rb +0 -88
  133. data/lib/geocoder/results/geocoder_us.rb +0 -39
  134. data/lib/geocoder/results/okf.rb +0 -106
  135. data/lib/geocoder/results/ovi.rb +0 -62
  136. data/lib/geocoder/results/yahoo.rb +0 -55
  137. data/lib/oauth_util.rb +0 -112
  138. data/test/fixtures/baidu_invalid_key +0 -1
  139. data/test/fixtures/baidu_ip_202_198_16_3 +0 -19
  140. data/test/fixtures/baidu_ip_invalid_key +0 -1
  141. data/test/fixtures/baidu_ip_no_results +0 -1
  142. data/test/fixtures/baidu_no_results +0 -1
  143. data/test/fixtures/baidu_reverse +0 -1
  144. data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
  145. data/test/fixtures/bing_invalid_key +0 -1
  146. data/test/fixtures/bing_madison_square_garden +0 -40
  147. data/test/fixtures/bing_no_results +0 -16
  148. data/test/fixtures/bing_reverse +0 -42
  149. data/test/fixtures/cloudmade_invalid_key +0 -1
  150. data/test/fixtures/cloudmade_madison_square_garden +0 -1
  151. data/test/fixtures/cloudmade_no_results +0 -1
  152. data/test/fixtures/esri_madison_square_garden +0 -59
  153. data/test/fixtures/esri_no_results +0 -8
  154. data/test/fixtures/esri_reverse +0 -21
  155. data/test/fixtures/freegeoip_74_200_247_59 +0 -12
  156. data/test/fixtures/freegeoip_no_results +0 -1
  157. data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
  158. data/test/fixtures/geocoder_ca_no_results +0 -1
  159. data/test/fixtures/geocoder_ca_reverse +0 -34
  160. data/test/fixtures/geocoder_us_madison_square_garden +0 -1
  161. data/test/fixtures/geocoder_us_no_results +0 -1
  162. data/test/fixtures/geocodio_1101_pennsylvania_ave +0 -1
  163. data/test/fixtures/geocodio_bad_api_key +0 -3
  164. data/test/fixtures/geocodio_invalid +0 -4
  165. data/test/fixtures/geocodio_no_results +0 -1
  166. data/test/fixtures/geocodio_over_query_limit +0 -4
  167. data/test/fixtures/google_garbage +0 -456
  168. data/test/fixtures/google_madison_square_garden +0 -57
  169. data/test/fixtures/google_no_city_data +0 -44
  170. data/test/fixtures/google_no_locality +0 -51
  171. data/test/fixtures/google_no_results +0 -4
  172. data/test/fixtures/google_over_limit +0 -4
  173. data/test/fixtures/google_places_details_invalid_request +0 -4
  174. data/test/fixtures/google_places_details_madison_square_garden +0 -120
  175. data/test/fixtures/google_places_details_no_results +0 -4
  176. data/test/fixtures/google_places_details_no_reviews +0 -60
  177. data/test/fixtures/google_places_details_no_types +0 -66
  178. data/test/fixtures/here_madison_square_garden +0 -72
  179. data/test/fixtures/here_no_results +0 -8
  180. data/test/fixtures/mapquest_error +0 -16
  181. data/test/fixtures/mapquest_invalid_api_key +0 -16
  182. data/test/fixtures/mapquest_invalid_request +0 -16
  183. data/test/fixtures/mapquest_madison_square_garden +0 -52
  184. data/test/fixtures/mapquest_no_results +0 -16
  185. data/test/fixtures/maxmind_24_24_24_21 +0 -1
  186. data/test/fixtures/maxmind_24_24_24_22 +0 -1
  187. data/test/fixtures/maxmind_24_24_24_23 +0 -1
  188. data/test/fixtures/maxmind_24_24_24_24 +0 -1
  189. data/test/fixtures/maxmind_74_200_247_59 +0 -1
  190. data/test/fixtures/maxmind_invalid_key +0 -1
  191. data/test/fixtures/maxmind_no_results +0 -1
  192. data/test/fixtures/nominatim_madison_square_garden +0 -150
  193. data/test/fixtures/nominatim_no_results +0 -1
  194. data/test/fixtures/nominatim_over_limit +0 -1
  195. data/test/fixtures/okf_kirstinmaki +0 -67
  196. data/test/fixtures/okf_no_results +0 -4
  197. data/test/fixtures/opencagedata_invalid_api_key +0 -25
  198. data/test/fixtures/opencagedata_invalid_request +0 -26
  199. data/test/fixtures/opencagedata_madison_square_garden +0 -73
  200. data/test/fixtures/opencagedata_no_results +0 -29
  201. data/test/fixtures/opencagedata_over_limit +0 -31
  202. data/test/fixtures/ovi_madison_square_garden +0 -72
  203. data/test/fixtures/ovi_no_results +0 -8
  204. data/test/fixtures/pointpin_10_10_10_10 +0 -1
  205. data/test/fixtures/pointpin_555_555_555_555 +0 -1
  206. data/test/fixtures/pointpin_80_111_555_555 +0 -1
  207. data/test/fixtures/pointpin_no_results +0 -1
  208. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +0 -1
  209. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +0 -1
  210. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +0 -1
  211. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +0 -1
  212. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +0 -1
  213. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +0 -1
  214. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +0 -1
  215. data/test/fixtures/smarty_streets_11211 +0 -1
  216. data/test/fixtures/smarty_streets_madison_square_garden +0 -47
  217. data/test/fixtures/smarty_streets_no_results +0 -1
  218. data/test/fixtures/telize_10_10_10_10 +0 -1
  219. data/test/fixtures/telize_555_555_555_555 +0 -4
  220. data/test/fixtures/telize_74_200_247_59 +0 -1
  221. data/test/fixtures/telize_no_results +0 -1
  222. data/test/fixtures/yahoo_error +0 -1
  223. data/test/fixtures/yahoo_invalid_key +0 -2
  224. data/test/fixtures/yahoo_madison_square_garden +0 -52
  225. data/test/fixtures/yahoo_no_results +0 -10
  226. data/test/fixtures/yahoo_over_limit +0 -2
  227. data/test/fixtures/yandex_canada_rue_dupuis_14 +0 -446
  228. data/test/fixtures/yandex_invalid_key +0 -1
  229. data/test/fixtures/yandex_kremlin +0 -48
  230. data/test/fixtures/yandex_new_york +0 -1
  231. data/test/fixtures/yandex_no_city_and_town +0 -112
  232. data/test/fixtures/yandex_no_results +0 -16
  233. data/test/integration/http_client_test.rb +0 -31
  234. data/test/mongoid_test_helper.rb +0 -43
  235. data/test/test_helper.rb +0 -416
  236. data/test/unit/active_record_test.rb +0 -16
  237. data/test/unit/cache_test.rb +0 -37
  238. data/test/unit/calculations_test.rb +0 -220
  239. data/test/unit/configuration_test.rb +0 -55
  240. data/test/unit/error_handling_test.rb +0 -56
  241. data/test/unit/geocoder_test.rb +0 -78
  242. data/test/unit/https_test.rb +0 -17
  243. data/test/unit/ip_address_test.rb +0 -27
  244. data/test/unit/lookup_test.rb +0 -153
  245. data/test/unit/lookups/bing_test.rb +0 -68
  246. data/test/unit/lookups/dstk_test.rb +0 -26
  247. data/test/unit/lookups/esri_test.rb +0 -48
  248. data/test/unit/lookups/freegeoip_test.rb +0 -27
  249. data/test/unit/lookups/geocoder_ca_test.rb +0 -17
  250. data/test/unit/lookups/geocodio_test.rb +0 -55
  251. data/test/unit/lookups/geoip2_test.rb +0 -27
  252. data/test/unit/lookups/google_places_details_test.rb +0 -122
  253. data/test/unit/lookups/google_premier_test.rb +0 -22
  254. data/test/unit/lookups/google_test.rb +0 -84
  255. data/test/unit/lookups/mapquest_test.rb +0 -60
  256. data/test/unit/lookups/maxmind_local_test.rb +0 -28
  257. data/test/unit/lookups/maxmind_test.rb +0 -63
  258. data/test/unit/lookups/nominatim_test.rb +0 -31
  259. data/test/unit/lookups/okf_test.rb +0 -38
  260. data/test/unit/lookups/opencagedata_test.rb +0 -64
  261. data/test/unit/lookups/pointpin_test.rb +0 -30
  262. data/test/unit/lookups/postcode_anywhere_uk_test.rb +0 -70
  263. data/test/unit/lookups/smarty_streets_test.rb +0 -71
  264. data/test/unit/lookups/telize_test.rb +0 -36
  265. data/test/unit/lookups/yahoo_test.rb +0 -35
  266. data/test/unit/method_aliases_test.rb +0 -26
  267. data/test/unit/model_test.rb +0 -38
  268. data/test/unit/mongoid_test.rb +0 -47
  269. data/test/unit/near_test.rb +0 -87
  270. data/test/unit/oauth_util_test.rb +0 -31
  271. data/test/unit/proxy_test.rb +0 -37
  272. data/test/unit/query_test.rb +0 -52
  273. data/test/unit/rake_task_test.rb +0 -21
  274. data/test/unit/request_test.rb +0 -35
  275. data/test/unit/result_test.rb +0 -72
  276. data/test/unit/test_mode_test.rb +0 -70
@@ -24,7 +24,7 @@ module Geocoder::Result
24
24
  alias_method :country_code, :country
25
25
 
26
26
  def postal_code
27
- @data['address']['postalCode']
27
+ @data['address']['postalCode'].to_s
28
28
  end
29
29
 
30
30
  def coordinates
@@ -35,6 +35,10 @@ module Geocoder::Result
35
35
  @data['address']
36
36
  end
37
37
 
38
+ def viewport
39
+ @data['bbox']
40
+ end
41
+
38
42
  def self.response_attributes
39
43
  %w[bbox name confidence entityType]
40
44
  end
@@ -0,0 +1,58 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class DbIpCom < Base
5
+
6
+ def coordinates
7
+ ['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] }
8
+ end
9
+
10
+ def city
11
+ @data['city']
12
+ end
13
+
14
+ def district
15
+ @data['district']
16
+ end
17
+
18
+ def state_code
19
+ @data['stateProv']
20
+ end
21
+ alias_method :state, :state_code
22
+
23
+ def zip_code
24
+ @data['zipCode']
25
+ end
26
+ alias_method :postal_code, :zip_code
27
+
28
+ def country_name
29
+ @data['countryName']
30
+ end
31
+ alias_method :country, :country_name
32
+
33
+ def country_code
34
+ @data['countryCode']
35
+ end
36
+
37
+ def continent_name
38
+ @data['continentName']
39
+ end
40
+ alias_method :continent, :continent_name
41
+
42
+ def continent_code
43
+ @data['continentCode']
44
+ end
45
+
46
+ def time_zone
47
+ @data['timeZone']
48
+ end
49
+
50
+ def gmt_offset
51
+ @data['gmtOffset']
52
+ end
53
+
54
+ def currency_code
55
+ @data['currencyCode']
56
+ end
57
+ end
58
+ end
@@ -4,12 +4,16 @@ module Geocoder::Result
4
4
  class Esri < Base
5
5
 
6
6
  def address
7
- address = reverse_geocode? ? 'Address' : 'Match_addr'
8
- attributes[address]
7
+ address_key = reverse_geocode? ? 'Address' : 'Match_addr'
8
+ attributes[address_key]
9
9
  end
10
10
 
11
11
  def city
12
- attributes['City']
12
+ if !reverse_geocode? && is_city?
13
+ place_name
14
+ else
15
+ attributes['City']
16
+ end
13
17
  end
14
18
 
15
19
  def state_code
@@ -19,8 +23,8 @@ module Geocoder::Result
19
23
  alias_method :state, :state_code
20
24
 
21
25
  def country
22
- country = reverse_geocode? ? "CountryCode" : "Country"
23
- attributes[country]
26
+ country_key = reverse_geocode? ? "CountryCode" : "Country"
27
+ attributes[country_key]
24
28
  end
25
29
 
26
30
  alias_method :country_code, :country
@@ -29,10 +33,27 @@ module Geocoder::Result
29
33
  attributes['Postal']
30
34
  end
31
35
 
36
+ def place_name
37
+ place_name_key = reverse_geocode? ? "Address" : "PlaceName"
38
+ attributes[place_name_key]
39
+ end
40
+
41
+ def place_type
42
+ reverse_geocode? ? "Address" : attributes['Type']
43
+ end
44
+
32
45
  def coordinates
33
46
  [geometry["y"], geometry["x"]]
34
47
  end
35
48
 
49
+ def viewport
50
+ north = attributes['Ymax']
51
+ south = attributes['Ymin']
52
+ east = attributes['Xmax']
53
+ west = attributes['Xmin']
54
+ [south, west, north, east]
55
+ end
56
+
36
57
  private
37
58
 
38
59
  def attributes
@@ -47,5 +68,8 @@ module Geocoder::Result
47
68
  @data['locations'].nil?
48
69
  end
49
70
 
71
+ def is_city?
72
+ ['City', 'State Capital', 'National Capital'].include?(place_type)
73
+ end
50
74
  end
51
- end
75
+ end
@@ -3,11 +3,6 @@ require 'geocoder/results/base'
3
3
  module Geocoder::Result
4
4
  class Freegeoip < Base
5
5
 
6
- def address(format = :full)
7
- s = state_code.to_s == "" ? "" : ", #{state_code}"
8
- "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
9
- end
10
-
11
6
  def city
12
7
  @data['city']
13
8
  end
@@ -29,11 +24,11 @@ module Geocoder::Result
29
24
  end
30
25
 
31
26
  def postal_code
32
- @data['zipcode']
27
+ @data['zipcode'] || @data['zip_code']
33
28
  end
34
29
 
35
30
  def self.response_attributes
36
- %w[metrocode ip]
31
+ %w[metro_code ip]
37
32
  end
38
33
 
39
34
  response_attributes.each do |a|
@@ -16,17 +16,17 @@ module Geocoder::Result
16
16
  end
17
17
 
18
18
  def city
19
- @data['city']
19
+ @data['city'] or (@data['standard'] and @data['standard']['city']) or ""
20
20
  end
21
21
 
22
22
  def state
23
- @data['prov']
23
+ @data['prov'] or (@data['standard'] and @data['standard']['prov']) or ""
24
24
  end
25
25
 
26
26
  alias_method :state_code, :state
27
27
 
28
28
  def postal_code
29
- @data['postal']
29
+ @data['postal'] or (@data['standard'] and @data['standard']['postal']) or ""
30
30
  end
31
31
 
32
32
  def country
@@ -14,22 +14,34 @@ module Geocoder::Result
14
14
  address_components["suffix"]
15
15
  end
16
16
 
17
+ def street_address
18
+ [number, address_components["formatted_street"]].compact.join(' ')
19
+ end
20
+
17
21
  def state
18
22
  address_components["state"]
19
23
  end
20
24
  alias_method :state_code, :state
21
25
 
22
26
  def zip
23
- address_components["zip"]
27
+ # Postal code is not returned for Canada geocode results
28
+ address_components["zip"] || ""
24
29
  end
25
30
  alias_method :postal_code, :zip
26
31
 
27
32
  def country
28
- "United States" # Geocodio only supports the US
33
+ # Geocodio supports US and Canada, however they don't return the full
34
+ # country name.
35
+
36
+ if country_code == "CA"
37
+ "Canada"
38
+ else
39
+ "United States"
40
+ end
29
41
  end
30
42
 
31
43
  def country_code
32
- "US" # Geocodio only supports the US
44
+ address_components['country']
33
45
  end
34
46
 
35
47
  def city
@@ -3,51 +3,41 @@ require 'geocoder/results/base'
3
3
  module Geocoder
4
4
  module Result
5
5
  class Geoip2 < Base
6
- def address(format = :full)
7
- s = state.to_s == '' ? '' : ", #{state_code}"
8
- "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
9
- end
10
6
 
11
7
  def coordinates
12
- [latitude, longitude]
13
- end
14
-
15
- def latitude
16
- return 0.0 unless @data['location']
17
- @data['location']['latitude'].to_f
18
- end
19
-
20
- def longitude
21
- return 0.0 unless @data['location']
22
- @data['location']['longitude'].to_f
8
+ %w[latitude longitude].map do |l|
9
+ data.fetch('location', {}).fetch(l, 0.0)
10
+ end
23
11
  end
24
12
 
25
13
  def city
26
- return '' unless @data['city']
27
- @data['city']['names']['en']
14
+ fetch_name(
15
+ data.fetch('city', {}).fetch('names', {})
16
+ )
28
17
  end
29
18
 
30
19
  def state
31
- return '' unless @data['subdivisions']
32
- @data['subdivisions'][0]['names']['en']
20
+ fetch_name(
21
+ data.fetch('subdivisions', []).fetch(0, {}).fetch('names', {})
22
+ )
33
23
  end
34
24
 
35
25
  def state_code
36
- return '' unless @data['subdivisions']
37
- @data['subdivisions'][0]['iso_code']
26
+ data.fetch('subdivisions', []).fetch(0, {}).fetch('iso_code', '')
38
27
  end
39
28
 
40
29
  def country
41
- @data['country']['names']['en']
30
+ fetch_name(
31
+ data.fetch('country', {}).fetch('names', {})
32
+ )
42
33
  end
43
34
 
44
35
  def country_code
45
- @data['country']['iso_code']
36
+ data.fetch('country', {}).fetch('iso_code', '')
46
37
  end
47
38
 
48
39
  def postal_code
49
- return '' unless @data['postal']
50
- @data['postal']['code']
40
+ data.fetch('postal', {}).fetch('code', '')
51
41
  end
52
42
 
53
43
  def self.response_attributes
@@ -59,6 +49,28 @@ module Geocoder
59
49
  @data[a]
60
50
  end
61
51
  end
52
+
53
+ def language=(l)
54
+ @language = l.to_s
55
+ end
56
+
57
+ def language
58
+ @language ||= default_language
59
+ end
60
+
61
+ def data
62
+ @data.to_hash
63
+ end
64
+
65
+ private
66
+
67
+ def default_language
68
+ @default_language = Geocoder.config[:language].to_s
69
+ end
70
+
71
+ def fetch_name(names)
72
+ names[language] || names[default_language] || ''
73
+ end
62
74
  end
63
75
  end
64
76
  end
@@ -0,0 +1,71 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class GeoportailLu < Base
5
+
6
+ def coordinates
7
+ geomlonlat['coordinates'].reverse if geolocalized?
8
+ end
9
+
10
+ def address
11
+ full_address
12
+ end
13
+
14
+ def city
15
+ try_to_extract 'locality', detailled_address
16
+ end
17
+
18
+ def state
19
+ 'Luxembourg'
20
+ end
21
+
22
+ def state_code
23
+ 'LU'
24
+ end
25
+
26
+ def postal_code
27
+ try_to_extract 'zip', detailled_address
28
+ end
29
+
30
+ def street_address
31
+ [street_number, street].compact.join(' ')
32
+ end
33
+
34
+ def street_number
35
+ try_to_extract 'postnumber', detailled_address
36
+ end
37
+
38
+ def street
39
+ try_to_extract 'street', detailled_address
40
+ end
41
+
42
+ def full_address
43
+ data['address']
44
+ end
45
+
46
+ def geomlonlat
47
+ data['geomlonlat']
48
+ end
49
+
50
+ def detailled_address
51
+ data['AddressDetails']
52
+ end
53
+
54
+ alias_method :country, :state
55
+ alias_method :province, :state
56
+ alias_method :country_code, :state_code
57
+ alias_method :province_code, :state_code
58
+
59
+ private
60
+
61
+ def geolocalized?
62
+ !!try_to_extract('coordinates', geomlonlat)
63
+ end
64
+
65
+ def try_to_extract(key, hash)
66
+ if hash.is_a?(Hash) and hash.include?(key)
67
+ hash[key]
68
+ end
69
+ end
70
+ end
71
+ end
@@ -120,5 +120,31 @@ module Geocoder::Result
120
120
  def precision
121
121
  geometry['location_type'] if geometry
122
122
  end
123
+
124
+ def partial_match
125
+ @data['partial_match']
126
+ end
127
+
128
+ def place_id
129
+ @data['place_id']
130
+ end
131
+
132
+ def viewport
133
+ viewport = geometry['viewport'] || fail
134
+ bounding_box_from viewport
135
+ end
136
+
137
+ def bounds
138
+ bounding_box_from geometry['bounds']
139
+ end
140
+
141
+ private
142
+
143
+ def bounding_box_from(box)
144
+ return nil unless box
145
+ south, west = %w(lat lng).map { |c| box['southwest'][c] }
146
+ north, east = %w(lat lng).map { |c| box['northeast'][c] }
147
+ [south, west, north, east]
148
+ end
123
149
  end
124
150
  end
@@ -30,6 +30,10 @@ module Geocoder
30
30
  def website
31
31
  @data["website"]
32
32
  end
33
+
34
+ def photos
35
+ @data["photos"]
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -0,0 +1,52 @@
1
+ require "geocoder/results/google"
2
+
3
+ module Geocoder
4
+ module Result
5
+ class GooglePlacesSearch < Google
6
+
7
+ def types
8
+ @data["types"] || []
9
+ end
10
+
11
+ def rating
12
+ @data["rating"]
13
+ end
14
+
15
+ def photos
16
+ @data["photos"]
17
+ end
18
+
19
+ def city
20
+ ""
21
+ end
22
+
23
+ def state
24
+ ""
25
+ end
26
+
27
+ def state_code
28
+ ""
29
+ end
30
+
31
+ def province
32
+ ""
33
+ end
34
+
35
+ def province_code
36
+ ""
37
+ end
38
+
39
+ def postal_code
40
+ ""
41
+ end
42
+
43
+ def country
44
+ ""
45
+ end
46
+
47
+ def country_code
48
+ ""
49
+ end
50
+ end
51
+ end
52
+ end
@@ -17,9 +17,20 @@ module Geocoder::Result
17
17
  fail unless d = @data['Location']['DisplayPosition']
18
18
  [d['Latitude'].to_f, d['Longitude'].to_f]
19
19
  end
20
+
21
+ def route
22
+ address_data['Street']
23
+ end
24
+
25
+ def street_number
26
+ address_data['HouseNumber']
27
+ end
20
28
 
21
29
  def state
22
- address_data['County']
30
+ fail unless d = address_data['AdditionalData']
31
+ if v = d.find{|ad| ad['key']=='StateName'}
32
+ return v['value']
33
+ end
23
34
  end
24
35
 
25
36
  def province
@@ -53,6 +64,15 @@ module Geocoder::Result
53
64
  address_data['Country']
54
65
  end
55
66
 
67
+ def viewport
68
+ map_view = data['Location']['MapView'] || fail
69
+ south = map_view['BottomRight']['Latitude']
70
+ west = map_view['TopLeft']['Longitude']
71
+ north = map_view['TopLeft']['Latitude']
72
+ east = map_view['BottomRight']['Longitude']
73
+ [south, west, north, east]
74
+ end
75
+
56
76
  private # ----------------------------------------------------------------
57
77
 
58
78
  def address_data
@@ -0,0 +1,22 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ip2location < Base
5
+
6
+ def address(format = :full)
7
+ "#{city_name} #{zip_code}, #{country_name}".sub(/^[ ,]*/, '')
8
+ end
9
+
10
+ def self.response_attributes
11
+ %w[country_code country_name region_name city_name latitude longitude
12
+ zip_code time_zone isp domain net_speed idd_code area_code usage_type
13
+ weather_station_code weather_station_name mcc mnc mobile_brand elevation]
14
+ end
15
+
16
+ response_attributes.each do |attr|
17
+ define_method attr do
18
+ @data[attr] || ""
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class IpapiCom < Base
5
+
6
+ def coordinates
7
+ [lat, lon]
8
+ end
9
+
10
+ def address
11
+ "#{city}, #{state_code} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
12
+ end
13
+
14
+ def state
15
+ region_name
16
+ end
17
+
18
+ def state_code
19
+ region
20
+ end
21
+
22
+ def postal_code
23
+ zip
24
+ end
25
+
26
+ def country_code
27
+ @data['countryCode']
28
+ end
29
+
30
+ def region_name
31
+ @data['regionName']
32
+ end
33
+
34
+ def self.response_attributes
35
+ %w[country region city zip timezone isp org as reverse query status message mobile proxy lat lon]
36
+ end
37
+
38
+ response_attributes.each do |attribute|
39
+ define_method attribute do
40
+ @data[attribute]
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,40 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class IpdataCo < Base
5
+
6
+ def city
7
+ @data['city']
8
+ end
9
+
10
+ def state
11
+ @data['region']
12
+ end
13
+
14
+ def state_code
15
+ @data['region_code']
16
+ end
17
+
18
+ def country
19
+ @data['country_name']
20
+ end
21
+
22
+ def country_code
23
+ @data['country_code']
24
+ end
25
+
26
+ def postal_code
27
+ @data['postal']
28
+ end
29
+
30
+ def self.response_attributes
31
+ %w[ip asn organisation currency currency_symbol calling_code flag time_zone is_eu]
32
+ end
33
+
34
+ response_attributes.each do |a|
35
+ define_method a do
36
+ @data[a]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,59 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ipgeolocation < Base
5
+
6
+ def coordinates
7
+ [@data['latitude'].to_f, @data['longitude'].to_f]
8
+ end
9
+
10
+ def address(format = :full)
11
+ "#{city}, #{state} #{postal_code}, #{country_name}".sub(/^[ ,]*/, "")
12
+ end
13
+
14
+ def state
15
+ @data['state_prov']
16
+ end
17
+
18
+ def state_code
19
+ @data['state_prov']
20
+ end
21
+
22
+ def country
23
+ @data['country_name']
24
+ end
25
+
26
+ def country_code
27
+ @data['country_code2']
28
+ end
29
+
30
+ def postal_code
31
+ @data['zipcode']
32
+ end
33
+
34
+ def self.response_attributes
35
+ [
36
+ ['ip', ''],
37
+ ['hostname', ''],
38
+ ['continent_code', ''],
39
+ ['continent_name', ''],
40
+ ['country_code2', ''],
41
+ ['country_code3', ''],
42
+ ['country_name', ''],
43
+ ['country_capital',''],
44
+ ['district',''],
45
+ ['state_prov',''],
46
+ ['city', ''],
47
+ ['zipcode', ''],
48
+ ['time_zone', {}],
49
+ ['currency', {}]
50
+ ]
51
+ end
52
+
53
+ response_attributes.each do |attr, default|
54
+ define_method attr do
55
+ @data[attr] || default
56
+ end
57
+ end
58
+ end
59
+ end