geocoder 1.4.9 → 1.5.0

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.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +352 -958
  4. data/lib/generators/geocoder/config/templates/initializer.rb +1 -1
  5. data/lib/geocoder/cli.rb +2 -2
  6. data/lib/geocoder/configuration.rb +1 -1
  7. data/lib/geocoder/exceptions.rb +1 -1
  8. data/lib/geocoder/ip_address.rb +1 -1
  9. data/lib/geocoder/lookup.rb +1 -2
  10. data/lib/geocoder/lookups/amap.rb +7 -3
  11. data/lib/geocoder/lookups/baidu.rb +14 -10
  12. data/lib/geocoder/lookups/baidu_ip.rb +6 -35
  13. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +4 -4
  14. data/lib/geocoder/lookups/base.rb +21 -3
  15. data/lib/geocoder/lookups/bing.rb +8 -12
  16. data/lib/geocoder/lookups/db_ip_com.rb +9 -6
  17. data/lib/geocoder/lookups/dstk.rb +4 -2
  18. data/lib/geocoder/lookups/esri.rb +1 -16
  19. data/lib/geocoder/lookups/freegeoip.rb +4 -0
  20. data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
  21. data/lib/geocoder/lookups/geocoder_us.rb +17 -9
  22. data/lib/geocoder/lookups/geocodio.rb +5 -5
  23. data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
  24. data/lib/geocoder/lookups/google.rb +8 -8
  25. data/lib/geocoder/lookups/google_places_details.rb +4 -4
  26. data/lib/geocoder/lookups/google_places_search.rb +4 -4
  27. data/lib/geocoder/lookups/google_premier.rb +10 -0
  28. data/lib/geocoder/lookups/here.rb +4 -4
  29. data/lib/geocoder/lookups/ip2location.rb +74 -0
  30. data/lib/geocoder/lookups/ipapi_com.rb +7 -12
  31. data/lib/geocoder/lookups/ipdata_co.rb +4 -0
  32. data/lib/geocoder/lookups/ipinfo_io.rb +10 -19
  33. data/lib/geocoder/lookups/ipstack.rb +9 -10
  34. data/lib/geocoder/lookups/latlon.rb +4 -4
  35. data/lib/geocoder/lookups/location_iq.rb +10 -4
  36. data/lib/geocoder/lookups/mapbox.rb +7 -6
  37. data/lib/geocoder/lookups/mapquest.rb +4 -5
  38. data/lib/geocoder/lookups/maxmind.rb +4 -4
  39. data/lib/geocoder/lookups/maxmind_geoip2.rb +4 -0
  40. data/lib/geocoder/lookups/nominatim.rb +4 -4
  41. data/lib/geocoder/lookups/opencagedata.rb +6 -5
  42. data/lib/geocoder/lookups/pelias.rb +6 -6
  43. data/lib/geocoder/lookups/pickpoint.rb +9 -3
  44. data/lib/geocoder/lookups/pointpin.rb +7 -6
  45. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
  46. data/lib/geocoder/lookups/postcodes_io.rb +6 -3
  47. data/lib/geocoder/lookups/smarty_streets.rb +8 -8
  48. data/lib/geocoder/lookups/telize.rb +21 -1
  49. data/lib/geocoder/lookups/yandex.rb +4 -4
  50. data/lib/geocoder/results/baidu.rb +10 -10
  51. data/lib/geocoder/results/base.rb +13 -1
  52. data/lib/geocoder/results/bing.rb +1 -1
  53. data/lib/geocoder/results/db_ip_com.rb +0 -5
  54. data/lib/geocoder/results/freegeoip.rb +0 -5
  55. data/lib/geocoder/results/geocoder_ca.rb +3 -3
  56. data/lib/geocoder/results/geoip2.rb +0 -4
  57. data/lib/geocoder/results/geoportail_lu.rb +5 -3
  58. data/lib/geocoder/results/ip2location.rb +22 -0
  59. data/lib/geocoder/results/ipdata_co.rb +0 -5
  60. data/lib/geocoder/results/maxmind.rb +0 -5
  61. data/lib/geocoder/results/maxmind_local.rb +0 -5
  62. data/lib/geocoder/results/telize.rb +0 -5
  63. data/lib/geocoder/results/test.rb +1 -1
  64. data/lib/geocoder/stores/active_record.rb +0 -2
  65. data/lib/geocoder/version.rb +1 -1
  66. metadata +5 -7
  67. data/lib/geocoder/lookups/okf.rb +0 -44
  68. data/lib/geocoder/lookups/ovi.rb +0 -62
  69. data/lib/geocoder/results/okf.rb +0 -106
  70. data/lib/geocoder/results/ovi.rb +0 -71
@@ -1,7 +1,7 @@
1
1
  Geocoder.configure(
2
2
  # Geocoding options
3
3
  # timeout: 3, # geocoding service timeout (secs)
4
- # lookup: :google, # name of geocoding service (symbol)
4
+ # lookup: :nominatim, # name of geocoding service (symbol)
5
5
  # ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol)
6
6
  # language: :en, # ISO-639 language code
7
7
  # use_https: false, # use HTTPS for lookup requests? (if supported)
@@ -97,7 +97,7 @@ module Geocoder
97
97
  end
98
98
 
99
99
  if (result = Geocoder.search(query).first)
100
- google = Geocoder::Lookup.get(:google)
100
+ nominatim = Geocoder::Lookup.get(:nominatim)
101
101
  lines = [
102
102
  ["Latitude", result.latitude],
103
103
  ["Longitude", result.longitude],
@@ -106,7 +106,7 @@ module Geocoder
106
106
  ["State/province", result.state],
107
107
  ["Postal code", result.postal_code],
108
108
  ["Country", result.country],
109
- ["Google map", google.map_link_url(result.coordinates)],
109
+ ["Map", nominatim.map_link_url(result.coordinates)],
110
110
  ]
111
111
  lines.each do |line|
112
112
  out << (line[0] + ": ").ljust(18) + line[1].to_s + "\n"
@@ -97,7 +97,7 @@ module Geocoder
97
97
 
98
98
  # geocoding options
99
99
  @data[:timeout] = 3 # geocoding service timeout (secs)
100
- @data[:lookup] = :google # name of street address geocoding service (symbol)
100
+ @data[:lookup] = :nominatim # name of street address geocoding service (symbol)
101
101
  @data[:ip_lookup] = :ipinfo_io # name of IP address geocoding service (symbol)
102
102
  @data[:language] = :en # ISO-639 language code
103
103
  @data[:http_headers] = {} # HTTP headers for lookup
@@ -1,4 +1,4 @@
1
- require 'timeout' # required for Ruby 1.9.3
1
+ require 'timeout'
2
2
 
3
3
  module Geocoder
4
4
 
@@ -3,7 +3,7 @@ module Geocoder
3
3
  class IpAddress < String
4
4
 
5
5
  def loopback?
6
- valid? and (self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
6
+ valid? and !!(self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
7
7
  end
8
8
 
9
9
  def valid?
@@ -39,14 +39,12 @@ module Geocoder
39
39
  :mapquest,
40
40
  :mapzen,
41
41
  :opencagedata,
42
- :ovi,
43
42
  :pelias,
44
43
  :pickpoint,
45
44
  :here,
46
45
  :baidu,
47
46
  :geocodio,
48
47
  :smarty_streets,
49
- :okf,
50
48
  :postcode_anywhere_uk,
51
49
  :postcodes_io,
52
50
  :geoportail_lu,
@@ -75,6 +73,7 @@ module Geocoder
75
73
  :ipdata_co,
76
74
  :db_ip_com,
77
75
  :ipstack,
76
+ :ip2location
78
77
  ]
79
78
  end
80
79
 
@@ -12,13 +12,17 @@ module Geocoder::Lookup
12
12
  ["key"]
13
13
  end
14
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)
15
+ def supported_protocols
16
+ [:http]
18
17
  end
19
18
 
20
19
  private # ---------------------------------------------------------------
21
20
 
21
+ def base_query_url(query)
22
+ path = query.reverse_geocode? ? 'regeo' : 'geo'
23
+ "http://restapi.amap.com/v3/geocode/#{path}?"
24
+ end
25
+
22
26
  def results(query, reverse = false)
23
27
  return [] unless doc = fetch_data(query)
24
28
  case [doc['status'], doc['info']]
@@ -12,10 +12,6 @@ module Geocoder::Lookup
12
12
  ["key"]
13
13
  end
14
14
 
15
- def query_url(query)
16
- "#{protocol}://api.map.baidu.com/geocoder/v2/?" + url_query_string(query)
17
- end
18
-
19
15
  # HTTP only
20
16
  def supported_protocols
21
17
  [:http]
@@ -23,26 +19,34 @@ module Geocoder::Lookup
23
19
 
24
20
  private # ---------------------------------------------------------------
25
21
 
22
+ def base_query_url(query)
23
+ "#{protocol}://api.map.baidu.com/geocoder/v2/?"
24
+ end
25
+
26
+ def content_key
27
+ 'result'
28
+ end
29
+
26
30
  def results(query, reverse = false)
27
31
  return [] unless doc = fetch_data(query)
28
32
  case doc['status']
29
33
  when 0
30
- return [doc['result']] unless doc['result'].blank?
34
+ return [doc[content_key]] unless doc[content_key].blank?
31
35
  when 1, 3, 4
32
36
  raise_error(Geocoder::Error, "server error.") ||
33
- Geocoder.log(:warn, "Baidu Geocoding API error: server error.")
37
+ Geocoder.log(:warn, "#{name} Geocoding API error: server error.")
34
38
  when 2
35
39
  raise_error(Geocoder::InvalidRequest, "invalid request.") ||
36
- Geocoder.log(:warn, "Baidu Geocoding API error: invalid request.")
40
+ Geocoder.log(:warn, "#{name} Geocoding API error: invalid request.")
37
41
  when 5
38
42
  raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
39
- Geocoder.log(:warn, "Baidu Geocoding API error: invalid api key.")
43
+ Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
40
44
  when 101, 102, 200..299
41
45
  raise_error(Geocoder::RequestDenied, "request denied") ||
42
- Geocoder.log(:warn, "Baidu Geocoding API error: request denied.")
46
+ Geocoder.log(:warn, "#{name} Geocoding API error: request denied.")
43
47
  when 300..399
44
48
  raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
45
- Geocoder.log(:warn, "Baidu Geocoding API error: over query limit.")
49
+ Geocoder.log(:warn, "#{name} Geocoding API error: over query limit.")
46
50
  end
47
51
  return []
48
52
  end
@@ -2,49 +2,20 @@ require 'geocoder/lookups/base'
2
2
  require 'geocoder/results/baidu_ip'
3
3
 
4
4
  module Geocoder::Lookup
5
- class BaiduIp < Base
5
+ class BaiduIp < Baidu
6
6
 
7
7
  def name
8
8
  "Baidu IP"
9
9
  end
10
10
 
11
- def required_api_key_parts
12
- ["key"]
13
- end
14
-
15
- def query_url(query)
16
- "#{protocol}://api.map.baidu.com/location/ip?" + url_query_string(query)
17
- end
11
+ private # ---------------------------------------------------------------
18
12
 
19
- # HTTP only
20
- def supported_protocols
21
- [:http]
13
+ def base_query_url(query)
14
+ "#{protocol}://api.map.baidu.com/location/ip?"
22
15
  end
23
16
 
24
- private # ---------------------------------------------------------------
25
-
26
- def results(query, reverse = false)
27
- return [] unless doc = fetch_data(query)
28
- case doc['status']
29
- when 0
30
- return [doc['content']] unless doc['content'].blank?
31
- when 1, 3, 4
32
- raise_error(Geocoder::Error, "server error.") ||
33
- Geocoder.log(:warn, "Baidu IP Geocoding API error: server error.")
34
- when 2
35
- raise_error(Geocoder::InvalidRequest, "invalid request.") ||
36
- Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid request.")
37
- when 5
38
- raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
39
- Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid api key.")
40
- when 101, 102, 200..299
41
- raise_error(Geocoder::RequestDenied, "request denied.") ||
42
- Geocoder.log(:warn, "Baidu IP Geocoding API error: request denied.")
43
- when 300..399
44
- raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
45
- Geocoder.log(:warn, "Baidu IP Geocoding API error: over query limit.")
46
- end
47
- return []
17
+ def content_key
18
+ 'content'
48
19
  end
49
20
 
50
21
  def query_url_params(query)
@@ -14,13 +14,13 @@ module Geocoder::Lookup
14
14
  "https://www.openstreetmap.org/#map=19/#{coordinates.join('/')}"
15
15
  end
16
16
 
17
- def query_url(query)
17
+ private # ---------------------------------------------------------------
18
+
19
+ def base_query_url(query)
18
20
  method = query.reverse_geocode? ? "reverse" : "search"
19
- "#{protocol}://api-adresse.data.gouv.fr/#{method}/?" + url_query_string(query)
21
+ "#{protocol}://api-adresse.data.gouv.fr/#{method}/?"
20
22
  end
21
23
 
22
- private # ---------------------------------------------------------------
23
-
24
24
  def any_result?(doc)
25
25
  doc['features'].any?
26
26
  end
@@ -4,7 +4,6 @@ require 'uri'
4
4
 
5
5
  unless defined?(ActiveSupport::JSON)
6
6
  begin
7
- require 'rubygems' # for Ruby 1.8
8
7
  require 'json'
9
8
  rescue LoadError
10
9
  raise LoadError, "Please install the 'json' or 'json_pure' gem to parse geocoder results."
@@ -72,8 +71,12 @@ module Geocoder
72
71
  ##
73
72
  # URL to use for querying the geocoding engine.
74
73
  #
74
+ # Subclasses should not modify this method. Instead they should define
75
+ # base_query_url and url_query_string. If absolutely necessary to
76
+ # subclss this method, they must also subclass #cache_key.
77
+ #
75
78
  def query_url(query)
76
- fail
79
+ base_query_url(query) + url_query_string(query)
77
80
  end
78
81
 
79
82
  ##
@@ -97,6 +100,14 @@ module Geocoder
97
100
 
98
101
  private # -------------------------------------------------------------
99
102
 
103
+ ##
104
+ # String which, when concatenated with url_query_string(query)
105
+ # produces the full query URL. Should include the "?" a the end.
106
+ #
107
+ def base_query_url(query)
108
+ fail
109
+ end
110
+
100
111
  ##
101
112
  # An object with configuration data for this particular lookup.
102
113
  #
@@ -147,7 +158,14 @@ module Geocoder
147
158
  # something else (like the URL before OAuth encoding).
148
159
  #
149
160
  def cache_key(query)
150
- query_url(query)
161
+ base_query_url(query) + hash_to_query(cache_key_params(query))
162
+ end
163
+
164
+ def cache_key_params(query)
165
+ # omit api_key and token because they may vary among requests
166
+ query_url_params(query).reject do |key,value|
167
+ key.to_s.match /(key|token)/
168
+ end
151
169
  end
152
170
 
153
171
  ##
@@ -16,24 +16,20 @@ module Geocoder::Lookup
16
16
  ["key"]
17
17
  end
18
18
 
19
- def query_url(query)
20
- base_url(query) + url_query_string(query)
21
- end
22
-
23
19
  private # ---------------------------------------------------------------
24
20
 
25
- def base_url(query)
26
- url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations"
27
-
28
- if !query.reverse_geocode?
21
+ def base_query_url(query)
22
+ text = CGI.escape(query.sanitized_text.strip)
23
+ url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations/"
24
+ if query.reverse_geocode?
25
+ url + "#{text}?"
26
+ else
29
27
  if r = query.options[:region]
30
- url << "/#{r}"
28
+ url << "#{r}/"
31
29
  end
32
30
  # use the more forgiving 'unstructured' query format to allow special
33
31
  # chars, newlines, brackets, typos.
34
- url + "?q=" + URI.escape(query.sanitized_text.strip) + "&"
35
- else
36
- url + "/#{URI.escape(query.sanitized_text.strip)}?"
32
+ url + "?q=#{text}&"
37
33
  end
38
34
  end
39
35
 
@@ -16,15 +16,18 @@ module Geocoder::Lookup
16
16
  ['api_key']
17
17
  end
18
18
 
19
- def query_url(query)
20
- query_params = if query.options[:params]
21
- "?#{url_query_string(query)}"
22
- end
19
+ private # ----------------------------------------------------------------
23
20
 
24
- "#{protocol}://api.db-ip.com/v2/#{configuration.api_key}/#{query.sanitized_text}#{query_params}"
21
+ def base_query_url(query)
22
+ "#{protocol}://api.db-ip.com/v2/#{configuration.api_key}/#{query.sanitized_text}?"
25
23
  end
26
24
 
27
- private
25
+ ##
26
+ # Same as query_url but without the api key.
27
+ #
28
+ def cache_key(query)
29
+ "#{protocol}://api.db-ip.com/v2/#{query.sanitized_text}?" + hash_to_query(cache_key_params(query))
30
+ end
28
31
 
29
32
  def results(query)
30
33
  return [] unless (doc = fetch_data(query))
@@ -12,9 +12,11 @@ module Geocoder::Lookup
12
12
  "Data Science Toolkit"
13
13
  end
14
14
 
15
- def query_url(query)
15
+ private # ----------------------------------------------------------------
16
+
17
+ def base_query_url(query)
16
18
  host = configuration[:host] || "www.datasciencetoolkit.org"
17
- "#{protocol}://#{host}/maps/api/geocode/json?" + url_query_string(query)
19
+ "#{protocol}://#{host}/maps/api/geocode/json?"
18
20
  end
19
21
  end
20
22
  end
@@ -4,15 +4,11 @@ require 'geocoder/esri_token'
4
4
 
5
5
  module Geocoder::Lookup
6
6
  class Esri < Base
7
-
7
+
8
8
  def name
9
9
  "Esri"
10
10
  end
11
11
 
12
- def query_url(query)
13
- base_query_url(query) + url_query_string(query)
14
- end
15
-
16
12
  private # ---------------------------------------------------------------
17
13
 
18
14
  def base_query_url(query)
@@ -34,17 +30,6 @@ module Geocoder::Lookup
34
30
  end
35
31
  end
36
32
 
37
- def cache_key(query)
38
- base_query_url(query) + hash_to_query(cache_key_params(query))
39
- end
40
-
41
- def cache_key_params(query)
42
- # omit api_key and token because they may vary among requests
43
- query_url_params(query).reject do |key,value|
44
- [:api_key, :token].include?(key)
45
- end
46
- end
47
-
48
33
  def query_url_params(query)
49
34
  params = {
50
35
  :f => "pjson",
@@ -23,6 +23,10 @@ module Geocoder::Lookup
23
23
 
24
24
  private # ---------------------------------------------------------------
25
25
 
26
+ def cache_key(query)
27
+ query_url(query)
28
+ end
29
+
26
30
  def parse_raw_data(raw_data)
27
31
  raw_data.match(/^<html><title>404/) ? nil : super(raw_data)
28
32
  end
@@ -8,12 +8,12 @@ module Geocoder::Lookup
8
8
  "Geocoder.ca"
9
9
  end
10
10
 
11
- def query_url(query)
12
- "#{protocol}://geocoder.ca/?" + url_query_string(query)
13
- end
14
-
15
11
  private # ---------------------------------------------------------------
16
12
 
13
+ def base_query_url(query)
14
+ "#{protocol}://geocoder.ca/?"
15
+ end
16
+
17
17
  def results(query)
18
18
  return [] unless doc = fetch_data(query)
19
19
  if doc['error'].nil?
@@ -8,20 +8,28 @@ module Geocoder::Lookup
8
8
  "Geocoder.us"
9
9
  end
10
10
 
11
- def supported_protocols
12
- [:http]
13
- end
11
+ def supported_protocols
12
+ [:http]
13
+ end
14
+
15
+ private # ----------------------------------------------------------------
16
+
17
+ def base_query_url(query)
18
+ base_query_url_with_optional_key(configuration.api_key)
19
+ end
14
20
 
15
- def query_url(query)
21
+ def cache_key(query)
22
+ base_query_url_with_optional_key(nil) + url_query_string(query)
23
+ end
24
+
25
+ def base_query_url_with_optional_key(key = nil)
26
+ base = "#{protocol}://"
16
27
  if configuration.api_key
17
- "#{protocol}://#{configuration.api_key}@geocoder.us/member/service/csv/geocode?" + url_query_string(query)
18
- else
19
- "#{protocol}://geocoder.us/service/csv/geocode?" + url_query_string(query)
28
+ base << "#{configuration.api_key}@"
20
29
  end
30
+ base + "geocoder.us/member/service/csv/geocode?"
21
31
  end
22
32
 
23
- private
24
-
25
33
  def results(query)
26
34
  return [] unless doc = fetch_data(query)
27
35
  if doc[0].to_s =~ /^(\d+)\:/