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,124 @@
1
+ require 'singleton'
2
+ require 'geocoder/configuration_hash'
3
+
4
+ module Geocoder
5
+
6
+ ##
7
+ # Configuration options should be set by passing a hash:
8
+ #
9
+ # Geocoder.configure(
10
+ # :timeout => 5,
11
+ # :lookup => :yandex,
12
+ # :api_key => "2a9fsa983jaslfj982fjasd",
13
+ # :units => :km
14
+ # )
15
+ #
16
+ def self.configure(options = nil, &block)
17
+ if !options.nil?
18
+ Configuration.instance.configure(options)
19
+ end
20
+ end
21
+
22
+ ##
23
+ # Read-only access to the singleton's config data.
24
+ #
25
+ def self.config
26
+ Configuration.instance.data
27
+ end
28
+
29
+ ##
30
+ # Read-only access to lookup-specific config data.
31
+ #
32
+ def self.config_for_lookup(lookup_name)
33
+ data = config.clone
34
+ data.reject!{ |key,value| !Configuration::OPTIONS.include?(key) }
35
+ if config.has_key?(lookup_name)
36
+ data.merge!(config[lookup_name])
37
+ end
38
+ data
39
+ end
40
+
41
+ class Configuration
42
+ include Singleton
43
+
44
+ OPTIONS = [
45
+ :timeout,
46
+ :lookup,
47
+ :ip_lookup,
48
+ :language,
49
+ :http_headers,
50
+ :use_https,
51
+ :http_proxy,
52
+ :https_proxy,
53
+ :api_key,
54
+ :cache,
55
+ :cache_prefix,
56
+ :always_raise,
57
+ :units,
58
+ :distances
59
+ ]
60
+
61
+ attr_accessor :data
62
+
63
+ def self.set_defaults
64
+ instance.set_defaults
65
+ end
66
+
67
+ OPTIONS.each do |o|
68
+ define_method o do
69
+ @data[o]
70
+ end
71
+ define_method "#{o}=" do |value|
72
+ @data[o] = value
73
+ end
74
+ end
75
+
76
+ def configure(options)
77
+ @data.rmerge!(options)
78
+ end
79
+
80
+ def initialize # :nodoc
81
+ @data = Geocoder::ConfigurationHash.new
82
+ set_defaults
83
+ end
84
+
85
+ def set_defaults
86
+
87
+ # geocoding options
88
+ @data[:timeout] = 3 # geocoding service timeout (secs)
89
+ @data[:lookup] = :google # name of street address geocoding service (symbol)
90
+ @data[:ip_lookup] = :freegeoip # name of IP address geocoding service (symbol)
91
+ @data[:language] = :en # ISO-639 language code
92
+ @data[:http_headers] = {} # HTTP headers for lookup
93
+ @data[:use_https] = false # use HTTPS for lookup requests? (if supported)
94
+ @data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
95
+ @data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
96
+ @data[:api_key] = nil # API key for geocoding service
97
+ @data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
98
+ @data[:cache_prefix] = "geocoder:" # prefix (string) to use for all cache keys
99
+
100
+ # exceptions that should not be rescued by default
101
+ # (if you want to implement custom error handling);
102
+ # supports SocketError and TimeoutError
103
+ @data[:always_raise] = []
104
+
105
+ # calculation options
106
+ @data[:units] = :mi # :mi or :km
107
+ @data[:distances] = :linear # :linear or :spherical
108
+ end
109
+
110
+ instance_eval(OPTIONS.map do |option|
111
+ o = option.to_s
112
+ <<-EOS
113
+ def #{o}
114
+ instance.data[:#{o}]
115
+ end
116
+
117
+ def #{o}=(value)
118
+ instance.data[:#{o}] = value
119
+ end
120
+ EOS
121
+ end.join("\n\n"))
122
+
123
+ end
124
+ end
@@ -0,0 +1,11 @@
1
+ require 'hash_recursive_merge'
2
+
3
+ module Geocoder
4
+ class ConfigurationHash < Hash
5
+ include HashRecursiveMerge
6
+
7
+ def method_missing(meth, *args, &block)
8
+ has_key?(meth) ? self[meth] : super
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ module Geocoder
2
+
3
+ class Error < StandardError
4
+ end
5
+
6
+ class ConfigurationError < Error
7
+ end
8
+
9
+ class OverQueryLimitError < Error
10
+ end
11
+
12
+ class RequestDenied < Error
13
+ end
14
+
15
+ class InvalidRequest < Error
16
+ end
17
+
18
+ class InvalidApiKey < Error
19
+ end
20
+
21
+ end
@@ -0,0 +1,21 @@
1
+ module Geocoder
2
+ class IpAddress < String
3
+
4
+ def loopback?
5
+ valid? and (self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
6
+ end
7
+
8
+ def valid?
9
+ ipregex = %r{
10
+ \A( # String Starts
11
+ ((::ffff:)?((\d{1,3})\.){3}\d{1,3}) # Check for IPv4
12
+ | # .... Or
13
+ (\S+?(:\S+?){6}\S+) # Check for IPv6
14
+ | # .... Or
15
+ (::1) # IPv6 loopback
16
+ )\z
17
+ }x
18
+ !!self.match(ipregex)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,102 @@
1
+ module Geocoder
2
+ module Lookup
3
+ extend self
4
+
5
+ ##
6
+ # Array of valid Lookup service names.
7
+ #
8
+ def all_services
9
+ street_services + ip_services
10
+ end
11
+
12
+ ##
13
+ # Array of valid Lookup service names, excluding :test.
14
+ #
15
+ def all_services_except_test
16
+ all_services - [:test]
17
+ end
18
+
19
+ ##
20
+ # All street address lookup services, default first.
21
+ #
22
+ def street_services
23
+ [
24
+ :dstk,
25
+ :esri,
26
+ :google,
27
+ :google_premier,
28
+ :google_places_details,
29
+ :yahoo,
30
+ :bing,
31
+ :geocoder_ca,
32
+ :geocoder_us,
33
+ :yandex,
34
+ :nominatim,
35
+ :mapquest,
36
+ :opencagedata,
37
+ :ovi,
38
+ :here,
39
+ :baidu,
40
+ :geocodio,
41
+ :smarty_streets,
42
+ :okf,
43
+ :postcode_anywhere_uk,
44
+ :test,
45
+ :amap
46
+ ]
47
+ end
48
+
49
+ ##
50
+ # All IP address lookup services, default first.
51
+ #
52
+ def ip_services
53
+ [
54
+ :baidu_ip,
55
+ :freegeoip,
56
+ :geoip2,
57
+ :maxmind,
58
+ :maxmind_local,
59
+ :telize,
60
+ :pointpin
61
+ ]
62
+ end
63
+
64
+ ##
65
+ # Retrieve a Lookup object from the store.
66
+ # Use this instead of Geocoder::Lookup::X.new to get an
67
+ # already-configured Lookup object.
68
+ #
69
+ def get(name)
70
+ @services = {} unless defined?(@services)
71
+ @services[name] = spawn(name) unless @services.include?(name)
72
+ @services[name]
73
+ end
74
+
75
+
76
+ private # -----------------------------------------------------------------
77
+
78
+ ##
79
+ # Spawn a Lookup of the given name.
80
+ #
81
+ def spawn(name)
82
+ if all_services.include?(name)
83
+ Geocoder::Lookup.const_get(classify_name(name)).new
84
+ else
85
+ valids = all_services.map(&:inspect).join(", ")
86
+ raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
87
+ "(#{name.inspect} is not one of: #{valids})."
88
+ end
89
+ end
90
+
91
+ ##
92
+ # Convert an "underscore" version of a name into a "class" version.
93
+ #
94
+ def classify_name(filename)
95
+ filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
96
+ end
97
+ end
98
+ end
99
+
100
+ Geocoder::Lookup.all_services.each do |name|
101
+ require "geocoder/lookups/#{name}"
102
+ end
@@ -0,0 +1,55 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/amap"
3
+
4
+ module Geocoder::Lookup
5
+ class Amap < Base
6
+
7
+ def name
8
+ "AutoNavi"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["key"]
13
+ end
14
+
15
+ def query_url(query)
16
+ path = query.reverse_geocode? ? 'regeo' : 'geo'
17
+ "http://restapi.amap.com/v3/geocode/#{path}?" + url_query_string(query)
18
+ end
19
+
20
+ private # ---------------------------------------------------------------
21
+
22
+ def results(query, reverse = false)
23
+ return [] unless doc = fetch_data(query)
24
+ case doc['status']
25
+ when "1"
26
+ return [doc['regeocode']] unless doc['regeocode'].blank?
27
+ else
28
+ raise_error(Geocoder::Error, "server error.") ||
29
+ warn("#{self.name} Geocoding API error: server error.")
30
+ end
31
+ return []
32
+ end
33
+
34
+ def query_url_params(query)
35
+ params = {
36
+ :key => configuration.api_key,
37
+ :output => "json"
38
+ }
39
+ if query.reverse_geocode?
40
+ params[:location] = revert_coordinates(query.text)
41
+ params[:extensions] = "all"
42
+ params[:coordsys] = "gps"
43
+ else
44
+ params[:address] = query.sanitized_text
45
+ end
46
+ params.merge(super)
47
+ end
48
+
49
+ def revert_coordinates(text)
50
+ [text[1],text[0]].join(",")
51
+ end
52
+
53
+ end
54
+ end
55
+
@@ -0,0 +1,55 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/baidu"
3
+
4
+ module Geocoder::Lookup
5
+ class Baidu < Base
6
+
7
+ def name
8
+ "Baidu"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["key"]
13
+ end
14
+
15
+ def query_url(query)
16
+ "http://api.map.baidu.com/geocoder/v2/?" + url_query_string(query)
17
+ end
18
+
19
+ private # ---------------------------------------------------------------
20
+
21
+ def results(query, reverse = false)
22
+ return [] unless doc = fetch_data(query)
23
+ case doc['status']
24
+ when 0
25
+ return [doc['result']] unless doc['result'].blank?
26
+ when 1, 3, 4
27
+ raise_error(Geocoder::Error, "server error.") ||
28
+ warn("Baidu Geocoding API error: server error.")
29
+ when 2
30
+ raise_error(Geocoder::InvalidRequest, "invalid request.") ||
31
+ warn("Baidu Geocoding API error: invalid request.")
32
+ when 5
33
+ raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
34
+ warn("Baidu Geocoding API error: invalid api key.")
35
+ when 101, 102, 200..299
36
+ raise_error(Geocoder::RequestDenied, "request denied") ||
37
+ warn("Baidu Geocoding API error: request denied.")
38
+ when 300..399
39
+ raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
40
+ warn("Baidu Geocoding API error: over query limit.")
41
+ end
42
+ return []
43
+ end
44
+
45
+ def query_url_params(query)
46
+ {
47
+ (query.reverse_geocode? ? :location : :address) => query.sanitized_text,
48
+ :ak => configuration.api_key,
49
+ :output => "json"
50
+ }.merge(super)
51
+ end
52
+
53
+ end
54
+ end
55
+
@@ -0,0 +1,54 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/baidu_ip'
3
+
4
+ module Geocoder::Lookup
5
+ class BaiduIp < Base
6
+
7
+ def name
8
+ "Baidu IP"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["key"]
13
+ end
14
+
15
+ def query_url(query)
16
+ "http://api.map.baidu.com/location/ip?" + url_query_string(query)
17
+ end
18
+
19
+ private # ---------------------------------------------------------------
20
+
21
+ def results(query, reverse = false)
22
+ return [] unless doc = fetch_data(query)
23
+ case doc['status']
24
+ when 0
25
+ return [doc['content']] unless doc['content'].blank?
26
+ when 1, 3, 4
27
+ raise_error(Geocoder::Error, "server error.") ||
28
+ warn("Baidu IP Geocoding API error: server error.")
29
+ when 2
30
+ raise_error(Geocoder::InvalidRequest, "invalid request.") ||
31
+ warn("Baidu IP Geocoding API error: invalid request.")
32
+ when 5
33
+ raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
34
+ warn("Baidu IP Geocoding API error: invalid api key.")
35
+ when 101, 102, 200..299
36
+ raise_error(Geocoder::RequestDenied, "request denied.") ||
37
+ warn("Baidu IP Geocoding API error: request denied.")
38
+ when 300..399
39
+ raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
40
+ warn("Baidu IP Geocoding API error: over query limit.")
41
+ end
42
+ return []
43
+ end
44
+
45
+ def query_url_params(query)
46
+ {
47
+ :ip => query.sanitized_text,
48
+ :ak => configuration.api_key,
49
+ :coor => "bd09ll"
50
+ }.merge(super)
51
+ end
52
+
53
+ end
54
+ end