geocoder-kb 1.2.6

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 (248) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +31 -0
  4. data/CHANGELOG.md +384 -0
  5. data/LICENSE +20 -0
  6. data/README.md +1085 -0
  7. data/Rakefile +25 -0
  8. data/bin/geocode +5 -0
  9. data/examples/autoexpire_cache_dalli.rb +62 -0
  10. data/examples/autoexpire_cache_redis.rb +28 -0
  11. data/examples/cache_bypass.rb +48 -0
  12. data/examples/sidekiq_worker.rb +16 -0
  13. data/gemfiles/Gemfile.mongoid-2.4.x +16 -0
  14. data/lib/generators/geocoder/config/config_generator.rb +14 -0
  15. data/lib/generators/geocoder/config/templates/initializer.rb +21 -0
  16. data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +28 -0
  17. data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +28 -0
  18. data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
  19. data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
  20. data/lib/geocoder.rb +47 -0
  21. data/lib/geocoder/cache.rb +90 -0
  22. data/lib/geocoder/calculations.rb +428 -0
  23. data/lib/geocoder/cli.rb +121 -0
  24. data/lib/geocoder/configuration.rb +124 -0
  25. data/lib/geocoder/configuration_hash.rb +11 -0
  26. data/lib/geocoder/exceptions.rb +21 -0
  27. data/lib/geocoder/ip_address.rb +21 -0
  28. data/lib/geocoder/lookup.rb +102 -0
  29. data/lib/geocoder/lookups/amap.rb +55 -0
  30. data/lib/geocoder/lookups/baidu.rb +55 -0
  31. data/lib/geocoder/lookups/baidu_ip.rb +54 -0
  32. data/lib/geocoder/lookups/base.rb +302 -0
  33. data/lib/geocoder/lookups/bing.rb +59 -0
  34. data/lib/geocoder/lookups/dstk.rb +20 -0
  35. data/lib/geocoder/lookups/esri.rb +48 -0
  36. data/lib/geocoder/lookups/freegeoip.rb +47 -0
  37. data/lib/geocoder/lookups/geocoder_ca.rb +54 -0
  38. data/lib/geocoder/lookups/geocoder_us.rb +39 -0
  39. data/lib/geocoder/lookups/geocodio.rb +42 -0
  40. data/lib/geocoder/lookups/geoip2.rb +40 -0
  41. data/lib/geocoder/lookups/google.rb +67 -0
  42. data/lib/geocoder/lookups/google_places_details.rb +50 -0
  43. data/lib/geocoder/lookups/google_premier.rb +47 -0
  44. data/lib/geocoder/lookups/here.rb +62 -0
  45. data/lib/geocoder/lookups/mapquest.rb +60 -0
  46. data/lib/geocoder/lookups/maxmind.rb +90 -0
  47. data/lib/geocoder/lookups/maxmind_local.rb +58 -0
  48. data/lib/geocoder/lookups/nominatim.rb +52 -0
  49. data/lib/geocoder/lookups/okf.rb +43 -0
  50. data/lib/geocoder/lookups/opencagedata.rb +58 -0
  51. data/lib/geocoder/lookups/ovi.rb +62 -0
  52. data/lib/geocoder/lookups/pointpin.rb +68 -0
  53. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +51 -0
  54. data/lib/geocoder/lookups/smarty_streets.rb +45 -0
  55. data/lib/geocoder/lookups/telize.rb +40 -0
  56. data/lib/geocoder/lookups/test.rb +44 -0
  57. data/lib/geocoder/lookups/yahoo.rb +88 -0
  58. data/lib/geocoder/lookups/yandex.rb +54 -0
  59. data/lib/geocoder/models/active_record.rb +50 -0
  60. data/lib/geocoder/models/base.rb +39 -0
  61. data/lib/geocoder/models/mongo_base.rb +64 -0
  62. data/lib/geocoder/models/mongo_mapper.rb +26 -0
  63. data/lib/geocoder/models/mongoid.rb +32 -0
  64. data/lib/geocoder/query.rb +111 -0
  65. data/lib/geocoder/railtie.rb +26 -0
  66. data/lib/geocoder/request.rb +25 -0
  67. data/lib/geocoder/results/amap.rb +85 -0
  68. data/lib/geocoder/results/baidu.rb +79 -0
  69. data/lib/geocoder/results/baidu_ip.rb +62 -0
  70. data/lib/geocoder/results/base.rb +67 -0
  71. data/lib/geocoder/results/bing.rb +48 -0
  72. data/lib/geocoder/results/dstk.rb +6 -0
  73. data/lib/geocoder/results/esri.rb +51 -0
  74. data/lib/geocoder/results/freegeoip.rb +45 -0
  75. data/lib/geocoder/results/geocoder_ca.rb +60 -0
  76. data/lib/geocoder/results/geocoder_us.rb +39 -0
  77. data/lib/geocoder/results/geocodio.rb +66 -0
  78. data/lib/geocoder/results/geoip2.rb +64 -0
  79. data/lib/geocoder/results/google.rb +124 -0
  80. data/lib/geocoder/results/google_places_details.rb +35 -0
  81. data/lib/geocoder/results/google_premier.rb +6 -0
  82. data/lib/geocoder/results/here.rb +62 -0
  83. data/lib/geocoder/results/mapquest.rb +51 -0
  84. data/lib/geocoder/results/maxmind.rb +135 -0
  85. data/lib/geocoder/results/maxmind_local.rb +49 -0
  86. data/lib/geocoder/results/nominatim.rb +94 -0
  87. data/lib/geocoder/results/okf.rb +106 -0
  88. data/lib/geocoder/results/opencagedata.rb +82 -0
  89. data/lib/geocoder/results/ovi.rb +62 -0
  90. data/lib/geocoder/results/pointpin.rb +44 -0
  91. data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
  92. data/lib/geocoder/results/smarty_streets.rb +106 -0
  93. data/lib/geocoder/results/telize.rb +45 -0
  94. data/lib/geocoder/results/test.rb +33 -0
  95. data/lib/geocoder/results/yahoo.rb +55 -0
  96. data/lib/geocoder/results/yandex.rb +84 -0
  97. data/lib/geocoder/sql.rb +107 -0
  98. data/lib/geocoder/stores/active_record.rb +289 -0
  99. data/lib/geocoder/stores/base.rb +127 -0
  100. data/lib/geocoder/stores/mongo_base.rb +89 -0
  101. data/lib/geocoder/stores/mongo_mapper.rb +13 -0
  102. data/lib/geocoder/stores/mongoid.rb +13 -0
  103. data/lib/geocoder/version.rb +3 -0
  104. data/lib/hash_recursive_merge.rb +74 -0
  105. data/lib/maxmind_database.rb +109 -0
  106. data/lib/oauth_util.rb +112 -0
  107. data/lib/tasks/geocoder.rake +29 -0
  108. data/lib/tasks/maxmind.rake +73 -0
  109. data/test/fixtures/baidu_invalid_key +1 -0
  110. data/test/fixtures/baidu_ip_202_198_16_3 +19 -0
  111. data/test/fixtures/baidu_ip_invalid_key +1 -0
  112. data/test/fixtures/baidu_ip_no_results +1 -0
  113. data/test/fixtures/baidu_no_results +1 -0
  114. data/test/fixtures/baidu_reverse +1 -0
  115. data/test/fixtures/baidu_shanghai_pearl_tower +12 -0
  116. data/test/fixtures/bing_invalid_key +1 -0
  117. data/test/fixtures/bing_madison_square_garden +40 -0
  118. data/test/fixtures/bing_no_results +16 -0
  119. data/test/fixtures/bing_reverse +42 -0
  120. data/test/fixtures/cloudmade_invalid_key +1 -0
  121. data/test/fixtures/cloudmade_madison_square_garden +1 -0
  122. data/test/fixtures/cloudmade_no_results +1 -0
  123. data/test/fixtures/esri_madison_square_garden +59 -0
  124. data/test/fixtures/esri_no_results +8 -0
  125. data/test/fixtures/esri_reverse +21 -0
  126. data/test/fixtures/freegeoip_74_200_247_59 +12 -0
  127. data/test/fixtures/freegeoip_no_results +1 -0
  128. data/test/fixtures/geocoder_ca_madison_square_garden +1 -0
  129. data/test/fixtures/geocoder_ca_no_results +1 -0
  130. data/test/fixtures/geocoder_ca_reverse +34 -0
  131. data/test/fixtures/geocoder_us_madison_square_garden +1 -0
  132. data/test/fixtures/geocoder_us_no_results +1 -0
  133. data/test/fixtures/geocodio_1101_pennsylvania_ave +1 -0
  134. data/test/fixtures/geocodio_bad_api_key +3 -0
  135. data/test/fixtures/geocodio_invalid +4 -0
  136. data/test/fixtures/geocodio_no_results +1 -0
  137. data/test/fixtures/geocodio_over_query_limit +4 -0
  138. data/test/fixtures/google_garbage +456 -0
  139. data/test/fixtures/google_madison_square_garden +57 -0
  140. data/test/fixtures/google_no_city_data +44 -0
  141. data/test/fixtures/google_no_locality +51 -0
  142. data/test/fixtures/google_no_results +4 -0
  143. data/test/fixtures/google_over_limit +4 -0
  144. data/test/fixtures/google_places_details_invalid_request +4 -0
  145. data/test/fixtures/google_places_details_madison_square_garden +120 -0
  146. data/test/fixtures/google_places_details_no_results +4 -0
  147. data/test/fixtures/google_places_details_no_reviews +60 -0
  148. data/test/fixtures/google_places_details_no_types +66 -0
  149. data/test/fixtures/here_madison_square_garden +72 -0
  150. data/test/fixtures/here_no_results +8 -0
  151. data/test/fixtures/mapquest_error +16 -0
  152. data/test/fixtures/mapquest_invalid_api_key +16 -0
  153. data/test/fixtures/mapquest_invalid_request +16 -0
  154. data/test/fixtures/mapquest_madison_square_garden +52 -0
  155. data/test/fixtures/mapquest_no_results +16 -0
  156. data/test/fixtures/maxmind_24_24_24_21 +1 -0
  157. data/test/fixtures/maxmind_24_24_24_22 +1 -0
  158. data/test/fixtures/maxmind_24_24_24_23 +1 -0
  159. data/test/fixtures/maxmind_24_24_24_24 +1 -0
  160. data/test/fixtures/maxmind_74_200_247_59 +1 -0
  161. data/test/fixtures/maxmind_invalid_key +1 -0
  162. data/test/fixtures/maxmind_no_results +1 -0
  163. data/test/fixtures/nominatim_madison_square_garden +150 -0
  164. data/test/fixtures/nominatim_no_results +1 -0
  165. data/test/fixtures/nominatim_over_limit +1 -0
  166. data/test/fixtures/okf_kirstinmaki +67 -0
  167. data/test/fixtures/okf_no_results +4 -0
  168. data/test/fixtures/opencagedata_invalid_api_key +25 -0
  169. data/test/fixtures/opencagedata_invalid_request +26 -0
  170. data/test/fixtures/opencagedata_madison_square_garden +73 -0
  171. data/test/fixtures/opencagedata_no_results +29 -0
  172. data/test/fixtures/opencagedata_over_limit +31 -0
  173. data/test/fixtures/ovi_madison_square_garden +72 -0
  174. data/test/fixtures/ovi_no_results +8 -0
  175. data/test/fixtures/pointpin_10_10_10_10 +1 -0
  176. data/test/fixtures/pointpin_555_555_555_555 +1 -0
  177. data/test/fixtures/pointpin_80_111_555_555 +1 -0
  178. data/test/fixtures/pointpin_no_results +1 -0
  179. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +1 -0
  180. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +1 -0
  181. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +1 -0
  182. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +1 -0
  183. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +1 -0
  184. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +1 -0
  185. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +1 -0
  186. data/test/fixtures/smarty_streets_11211 +1 -0
  187. data/test/fixtures/smarty_streets_madison_square_garden +47 -0
  188. data/test/fixtures/smarty_streets_no_results +1 -0
  189. data/test/fixtures/telize_10_10_10_10 +1 -0
  190. data/test/fixtures/telize_555_555_555_555 +4 -0
  191. data/test/fixtures/telize_74_200_247_59 +1 -0
  192. data/test/fixtures/telize_no_results +1 -0
  193. data/test/fixtures/yahoo_error +1 -0
  194. data/test/fixtures/yahoo_invalid_key +2 -0
  195. data/test/fixtures/yahoo_madison_square_garden +52 -0
  196. data/test/fixtures/yahoo_no_results +10 -0
  197. data/test/fixtures/yahoo_over_limit +2 -0
  198. data/test/fixtures/yandex_canada_rue_dupuis_14 +446 -0
  199. data/test/fixtures/yandex_invalid_key +1 -0
  200. data/test/fixtures/yandex_kremlin +48 -0
  201. data/test/fixtures/yandex_new_york +1 -0
  202. data/test/fixtures/yandex_no_city_and_town +112 -0
  203. data/test/fixtures/yandex_no_results +16 -0
  204. data/test/integration/http_client_test.rb +31 -0
  205. data/test/mongoid_test_helper.rb +43 -0
  206. data/test/test_helper.rb +416 -0
  207. data/test/unit/active_record_test.rb +16 -0
  208. data/test/unit/cache_test.rb +37 -0
  209. data/test/unit/calculations_test.rb +220 -0
  210. data/test/unit/configuration_test.rb +55 -0
  211. data/test/unit/error_handling_test.rb +56 -0
  212. data/test/unit/geocoder_test.rb +78 -0
  213. data/test/unit/https_test.rb +17 -0
  214. data/test/unit/ip_address_test.rb +27 -0
  215. data/test/unit/lookup_test.rb +153 -0
  216. data/test/unit/lookups/bing_test.rb +68 -0
  217. data/test/unit/lookups/dstk_test.rb +26 -0
  218. data/test/unit/lookups/esri_test.rb +48 -0
  219. data/test/unit/lookups/freegeoip_test.rb +27 -0
  220. data/test/unit/lookups/geocoder_ca_test.rb +17 -0
  221. data/test/unit/lookups/geocodio_test.rb +55 -0
  222. data/test/unit/lookups/geoip2_test.rb +27 -0
  223. data/test/unit/lookups/google_places_details_test.rb +122 -0
  224. data/test/unit/lookups/google_premier_test.rb +22 -0
  225. data/test/unit/lookups/google_test.rb +84 -0
  226. data/test/unit/lookups/mapquest_test.rb +60 -0
  227. data/test/unit/lookups/maxmind_local_test.rb +28 -0
  228. data/test/unit/lookups/maxmind_test.rb +63 -0
  229. data/test/unit/lookups/nominatim_test.rb +31 -0
  230. data/test/unit/lookups/okf_test.rb +38 -0
  231. data/test/unit/lookups/opencagedata_test.rb +64 -0
  232. data/test/unit/lookups/pointpin_test.rb +30 -0
  233. data/test/unit/lookups/postcode_anywhere_uk_test.rb +70 -0
  234. data/test/unit/lookups/smarty_streets_test.rb +71 -0
  235. data/test/unit/lookups/telize_test.rb +36 -0
  236. data/test/unit/lookups/yahoo_test.rb +35 -0
  237. data/test/unit/method_aliases_test.rb +26 -0
  238. data/test/unit/model_test.rb +38 -0
  239. data/test/unit/mongoid_test.rb +47 -0
  240. data/test/unit/near_test.rb +87 -0
  241. data/test/unit/oauth_util_test.rb +31 -0
  242. data/test/unit/proxy_test.rb +37 -0
  243. data/test/unit/query_test.rb +52 -0
  244. data/test/unit/rake_task_test.rb +21 -0
  245. data/test/unit/request_test.rb +35 -0
  246. data/test/unit/result_test.rb +72 -0
  247. data/test/unit/test_mode_test.rb +70 -0
  248. metadata +294 -0
@@ -0,0 +1,35 @@
1
+ require "geocoder/results/google"
2
+
3
+ module Geocoder
4
+ module Result
5
+ class GooglePlacesDetails < Google
6
+ def place_id
7
+ @data["place_id"]
8
+ end
9
+
10
+ def types
11
+ @data["types"] || []
12
+ end
13
+
14
+ def reviews
15
+ @data["reviews"] || []
16
+ end
17
+
18
+ def rating
19
+ @data["rating"]
20
+ end
21
+
22
+ def rating_count
23
+ @data["user_ratings_total"]
24
+ end
25
+
26
+ def phone_number
27
+ @data["international_phone_number"]
28
+ end
29
+
30
+ def website
31
+ @data["website"]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ require 'geocoder/results/google'
2
+
3
+ module Geocoder::Result
4
+ class GooglePremier < Google
5
+ end
6
+ end
@@ -0,0 +1,62 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Here < Base
5
+
6
+ ##
7
+ # A string in the given format.
8
+ #
9
+ def address(format = :full)
10
+ address_data['Label']
11
+ end
12
+
13
+ ##
14
+ # A two-element array: [lat, lon].
15
+ #
16
+ def coordinates
17
+ fail unless d = @data['Location']['DisplayPosition']
18
+ [d['Latitude'].to_f, d['Longitude'].to_f]
19
+ end
20
+
21
+ def state
22
+ address_data['County']
23
+ end
24
+
25
+ def province
26
+ address_data['County']
27
+ end
28
+
29
+ def postal_code
30
+ address_data['PostalCode']
31
+ end
32
+
33
+ def city
34
+ address_data['City']
35
+ end
36
+
37
+ def state_code
38
+ address_data['State']
39
+ end
40
+
41
+ def province_code
42
+ address_data['State']
43
+ end
44
+
45
+ def country
46
+ fail unless d = address_data['AdditionalData']
47
+ if v = d.find{|ad| ad['key']=='CountryName'}
48
+ return v['value']
49
+ end
50
+ end
51
+
52
+ def country_code
53
+ address_data['Country']
54
+ end
55
+
56
+ private # ----------------------------------------------------------------
57
+
58
+ def address_data
59
+ @data['Location']['Address'] || fail
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,51 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Mapquest < Base
5
+ def latitude
6
+ @data["latLng"]["lat"]
7
+ end
8
+
9
+ def longitude
10
+ @data["latLng"]["lng"]
11
+ end
12
+
13
+ def coordinates
14
+ [latitude, longitude]
15
+ end
16
+
17
+ def city
18
+ @data['adminArea5']
19
+ end
20
+
21
+ def street
22
+ @data['street']
23
+ end
24
+
25
+ def state
26
+ @data['adminArea3']
27
+ end
28
+
29
+ alias_method :state_code, :state
30
+
31
+ #FIXME: these might not be right, unclear with MQ documentation
32
+ alias_method :province, :state
33
+ alias_method :province_code, :state
34
+
35
+ def postal_code
36
+ @data['postalCode'].to_s
37
+ end
38
+
39
+ def country
40
+ @data['adminArea1']
41
+ end
42
+
43
+ def country_code
44
+ country
45
+ end
46
+
47
+ def address
48
+ [street, city, state, postal_code, country].reject{|s| s.length == 0 }.join(", ")
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,135 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Maxmind < Base
5
+
6
+ ##
7
+ # Hash mapping service names to names of returned fields.
8
+ #
9
+ def self.field_names
10
+ {
11
+ :country => [
12
+ :country_code,
13
+ :error
14
+ ],
15
+
16
+ :city => [
17
+ :country_code,
18
+ :region_code,
19
+ :city_name,
20
+ :latitude,
21
+ :longitude,
22
+ :error
23
+ ],
24
+
25
+ :city_isp_org => [
26
+ :country_code,
27
+ :region_code,
28
+ :city_name,
29
+ :postal_code,
30
+ :latitude,
31
+ :longitude,
32
+ :metro_code,
33
+ :area_code,
34
+ :isp_name,
35
+ :organization_name,
36
+ :error
37
+ ],
38
+
39
+ :omni => [
40
+ :country_code,
41
+ :country_name,
42
+ :region_code,
43
+ :region_name,
44
+ :city_name,
45
+ :latitude,
46
+ :longitude,
47
+ :metro_code,
48
+ :area_code,
49
+ :time_zone,
50
+ :continent_code,
51
+ :postal_code,
52
+ :isp_name,
53
+ :organization_name,
54
+ :domain,
55
+ :as_number,
56
+ :netspeed,
57
+ :user_type,
58
+ :accuracy_radius,
59
+ :country_confidence_factor,
60
+ :city_confidence_factor,
61
+ :region_confidence_factor,
62
+ :postal_confidence_factor,
63
+ :error
64
+ ]
65
+ }
66
+ end
67
+
68
+ ##
69
+ # Name of the MaxMind service being used.
70
+ #
71
+ def service_name
72
+ # it would be much better to infer this from the length of the @data
73
+ # array, but MaxMind seems to send inconsistent and wide-ranging response
74
+ # lengths (see https://github.com/alexreisner/geocoder/issues/396)
75
+ Geocoder.config.maxmind[:service]
76
+ end
77
+
78
+ def field_names
79
+ self.class.field_names[service_name]
80
+ end
81
+
82
+ def data_hash
83
+ @data_hash ||= Hash[*field_names.zip(@data).flatten]
84
+ end
85
+
86
+ def coordinates
87
+ [data_hash[:latitude].to_f, data_hash[:longitude].to_f]
88
+ end
89
+
90
+ def address(format = :full)
91
+ s = state_code.to_s == "" ? "" : ", #{state_code}"
92
+ "#{city}#{s} #{postal_code}, #{country_code}".sub(/^[ ,]*/, "")
93
+ end
94
+
95
+ def city
96
+ data_hash[:city_name]
97
+ end
98
+
99
+ def state # not given by MaxMind
100
+ data_hash[:region_name] || data_hash[:region_code]
101
+ end
102
+
103
+ def state_code
104
+ data_hash[:region_code]
105
+ end
106
+
107
+ def country #not given by MaxMind
108
+ data_hash[:country_name] || data_hash[:country_code]
109
+ end
110
+
111
+ def country_code
112
+ data_hash[:country_code]
113
+ end
114
+
115
+ def postal_code
116
+ data_hash[:postal_code]
117
+ end
118
+
119
+ def method_missing(method, *args, &block)
120
+ if field_names.include?(method)
121
+ data_hash[method]
122
+ else
123
+ super
124
+ end
125
+ end
126
+
127
+ def respond_to?(method)
128
+ if field_names.include?(method)
129
+ true
130
+ else
131
+ super
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,49 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class MaxmindLocal < Base
5
+
6
+ def address(format = :full)
7
+ s = state.to_s == "" ? "" : ", #{state}"
8
+ "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
9
+ end
10
+
11
+ def coordinates
12
+ [@data[:latitude], @data[:longitude]]
13
+ end
14
+
15
+ def city
16
+ @data[:city_name]
17
+ end
18
+
19
+ def state
20
+ @data[:region_name]
21
+ end
22
+
23
+ def state_code
24
+ "" # Not available in Maxmind's database
25
+ end
26
+
27
+ def country
28
+ @data[:country_name]
29
+ end
30
+
31
+ def country_code
32
+ @data[:country_code2]
33
+ end
34
+
35
+ def postal_code
36
+ @data[:postal_code]
37
+ end
38
+
39
+ def self.response_attributes
40
+ %w[ip]
41
+ end
42
+
43
+ response_attributes.each do |a|
44
+ define_method a do
45
+ @data[a]
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,94 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Nominatim < Base
5
+
6
+ def poi
7
+ %w[stadium bus_stop tram_stop].each do |key|
8
+ return @data['address'][key] if @data['address'].key?(key)
9
+ end
10
+ return nil
11
+ end
12
+
13
+ def house_number
14
+ @data['address']['house_number']
15
+ end
16
+
17
+ def address
18
+ @data['display_name']
19
+ end
20
+
21
+ def street
22
+ %w[road pedestrian highway].each do |key|
23
+ return @data['address'][key] if @data['address'].key?(key)
24
+ end
25
+ return nil
26
+ end
27
+
28
+ def city
29
+ %w[city town village hamlet].each do |key|
30
+ return @data['address'][key] if @data['address'].key?(key)
31
+ end
32
+ return nil
33
+ end
34
+
35
+ def village
36
+ @data['address']['village']
37
+ end
38
+
39
+ def town
40
+ @data['address']['town']
41
+ end
42
+
43
+ def state
44
+ @data['address']['state']
45
+ end
46
+
47
+ alias_method :state_code, :state
48
+
49
+ def postal_code
50
+ @data['address']['postcode']
51
+ end
52
+
53
+ def county
54
+ @data['address']['county']
55
+ end
56
+
57
+ def country
58
+ @data['address']['country']
59
+ end
60
+
61
+ def country_code
62
+ @data['address']['country_code']
63
+ end
64
+
65
+ def suburb
66
+ @data['address']['suburb']
67
+ end
68
+
69
+ def coordinates
70
+ [@data['lat'].to_f, @data['lon'].to_f]
71
+ end
72
+
73
+ def place_class
74
+ @data['class']
75
+ end
76
+
77
+ def place_type
78
+ @data['type']
79
+ end
80
+
81
+ def self.response_attributes
82
+ %w[place_id osm_type osm_id boundingbox license
83
+ polygonpoints display_name class type stadium]
84
+ end
85
+
86
+ response_attributes.each do |a|
87
+ unless method_defined?(a)
88
+ define_method a do
89
+ @data[a]
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,106 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Okf < Base
5
+
6
+ def coordinates
7
+ ['lat', 'lng'].map{ |i| geometry['location'][i] }
8
+ end
9
+
10
+ def address(format = :full)
11
+ formatted_address
12
+ end
13
+
14
+ def city
15
+ fields = [:locality, :sublocality,
16
+ :administrative_area_level_3,
17
+ :administrative_area_level_2]
18
+ fields.each do |f|
19
+ if entity = address_components_of_type(f).first
20
+ return entity['long_name']
21
+ end
22
+ end
23
+ return nil # no appropriate components found
24
+ end
25
+
26
+ def state
27
+ ""
28
+ end
29
+
30
+ def sub_state
31
+ ""
32
+ end
33
+
34
+ def state_code
35
+ ""
36
+ end
37
+
38
+ def country
39
+ if country = address_components_of_type(:country).first
40
+ country['long_name']
41
+ end
42
+ end
43
+
44
+ def country_code
45
+ if country = address_components_of_type(:country).first
46
+ country['short_name']
47
+ end
48
+ end
49
+
50
+ def postal_code
51
+ if postal = address_components_of_type(:postal_code).first
52
+ postal['long_name']
53
+ end
54
+ end
55
+
56
+ def route
57
+ if route = address_components_of_type(:route).first
58
+ route['long_name']
59
+ end
60
+ end
61
+
62
+ def street_number
63
+ if street_number = address_components_of_type(:street_number).first
64
+ street_number['long_name']
65
+ end
66
+ end
67
+
68
+ def street_address
69
+ [route, street_number].compact.join(' ')
70
+ end
71
+
72
+ def types
73
+ @data['types']
74
+ end
75
+
76
+ def formatted_address
77
+ @data['formatted_address']
78
+ end
79
+
80
+ def address_components
81
+ @data['address_components']
82
+ end
83
+
84
+ ##
85
+ # Get address components of a given type. Valid types are defined in
86
+ # Google's Geocoding API documentation and include (among others):
87
+ #
88
+ # :street_number
89
+ # :locality
90
+ # :neighborhood
91
+ # :route
92
+ # :postal_code
93
+ #
94
+ def address_components_of_type(type)
95
+ address_components.select{ |c| c['types'].include?(type.to_s) }
96
+ end
97
+
98
+ def geometry
99
+ @data['geometry']
100
+ end
101
+
102
+ def precision
103
+ geometry['location_type'] if geometry
104
+ end
105
+ end
106
+ end