geocoder 1.4.9 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

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
@@ -9,12 +9,12 @@ module Geocoder::Lookup
9
9
  "MaxMind"
10
10
  end
11
11
 
12
- def query_url(query)
13
- "#{protocol}://geoip.maxmind.com/#{service_code}?" + url_query_string(query)
14
- end
15
-
16
12
  private # ---------------------------------------------------------------
17
13
 
14
+ def base_query_url(query)
15
+ "#{protocol}://geoip.maxmind.com/#{service_code}?"
16
+ end
17
+
18
18
  ##
19
19
  # Return the name of the configured service, or raise an exception.
20
20
  #
@@ -20,6 +20,10 @@ module Geocoder::Lookup
20
20
 
21
21
  private # ---------------------------------------------------------------
22
22
 
23
+ def cache_key(query)
24
+ query_url(query)
25
+ end
26
+
23
27
  ##
24
28
  # Return the name of the configured service, or raise an exception.
25
29
  #
@@ -12,13 +12,13 @@ module Geocoder::Lookup
12
12
  "https://www.openstreetmap.org/?lat=#{coordinates[0]}&lon=#{coordinates[1]}&zoom=15&layers=M"
13
13
  end
14
14
 
15
- def query_url(query)
15
+ private # ---------------------------------------------------------------
16
+
17
+ def base_query_url(query)
16
18
  method = query.reverse_geocode? ? "reverse" : "search"
17
- "#{protocol}://#{configured_host}/#{method}?" + url_query_string(query)
19
+ "#{protocol}://#{configured_host}/#{method}?"
18
20
  end
19
21
 
20
- private # ---------------------------------------------------------------
21
-
22
22
  def configured_host
23
23
  configuration[:host] || "nominatim.openstreetmap.org"
24
24
  end
@@ -8,15 +8,15 @@ module Geocoder::Lookup
8
8
  "OpenCageData"
9
9
  end
10
10
 
11
- def query_url(query)
12
- "#{protocol}://api.opencagedata.com/geocode/v1/json?key=#{configuration.api_key}&#{url_query_string(query)}"
13
- end
14
-
15
11
  def required_api_key_parts
16
12
  ["key"]
17
13
  end
18
14
 
19
- private
15
+ private # ----------------------------------------------------------------
16
+
17
+ def base_query_url(query)
18
+ "#{protocol}://api.opencagedata.com/geocode/v1/json?"
19
+ end
20
20
 
21
21
  def results(query)
22
22
  return [] unless doc = fetch_data(query)
@@ -44,6 +44,7 @@ module Geocoder::Lookup
44
44
  def query_url_params(query)
45
45
  params = {
46
46
  :q => query.sanitized_text,
47
+ :key => configuration.api_key,
47
48
  :language => (query.language || configuration.language)
48
49
  }.merge(super)
49
50
 
@@ -11,16 +11,16 @@ module Geocoder::Lookup
11
11
  configuration[:endpoint] || 'localhost'
12
12
  end
13
13
 
14
- def query_url(query)
15
- query_type = query.reverse_geocode? ? 'reverse' : 'search'
16
- "#{protocol}://#{endpoint}/v1/#{query_type}?" + url_query_string(query)
17
- end
18
-
19
14
  def required_api_key_parts
20
15
  ['search-XXXX']
21
16
  end
22
17
 
23
- private
18
+ private # ----------------------------------------------------------------
19
+
20
+ def base_query_url(query)
21
+ query_type = query.reverse_geocode? ? 'reverse' : 'search'
22
+ "#{protocol}://#{endpoint}/v1/#{query_type}?"
23
+ end
24
24
 
25
25
  def query_url_params(query)
26
26
  params = {
@@ -15,12 +15,18 @@ module Geocoder::Lookup
15
15
  ["api_key"]
16
16
  end
17
17
 
18
- def query_url(query)
18
+ private # ----------------------------------------------------------------
19
+
20
+ def base_query_url(query)
19
21
  method = query.reverse_geocode? ? "reverse" : "forward"
20
- "#{protocol}://api.pickpoint.io/v1/#{method}?key=#{configuration.api_key}&" + url_query_string(query)
22
+ "#{protocol}://api.pickpoint.io/v1/#{method}?"
21
23
  end
22
24
 
23
- private
25
+ def query_url_params(query)
26
+ params = {
27
+ key: configuration.api_key
28
+ }.merge(super)
29
+ end
24
30
 
25
31
  def results(query)
26
32
  return [] unless doc = fetch_data(query)
@@ -13,10 +13,14 @@ module Geocoder::Lookup
13
13
  end
14
14
 
15
15
  def query_url(query)
16
- "#{ protocol }://geo.pointp.in/#{ api_key }/json/#{ query.sanitized_text }"
16
+ "#{protocol}://geo.pointp.in/#{configuration.api_key}/json/#{query.sanitized_text}"
17
17
  end
18
18
 
19
- private
19
+ private # ----------------------------------------------------------------
20
+
21
+ def cache_key(query)
22
+ "#{protocol}://geo.pointp.in/json/#{query.sanitized_text}"
23
+ end
20
24
 
21
25
  def results(query)
22
26
  # don't look up a loopback address, just return the stored result
@@ -46,6 +50,7 @@ module Geocoder::Lookup
46
50
  parsed_data.keys.include?('error')
47
51
  end
48
52
 
53
+ # TODO: replace this hash with what's actually returned by Pointpin
49
54
  def reserved_result(ip)
50
55
  {
51
56
  "ip" => ip,
@@ -60,9 +65,5 @@ module Geocoder::Lookup
60
65
  "country_code" => "RD"
61
66
  }
62
67
  end
63
-
64
- def api_key
65
- configuration.api_key
66
- end
67
68
  end
68
69
  end
@@ -4,7 +4,6 @@ require 'geocoder/results/postcode_anywhere_uk'
4
4
  module Geocoder::Lookup
5
5
  class PostcodeAnywhereUk < Base
6
6
  # API documentation: http://www.postcodeanywhere.co.uk/Support/WebService/Geocoding/UK/Geocode/2/
7
- BASE_URL_GEOCODE_V2_00 = 'services.postcodeanywhere.co.uk/Geocoding/UK/Geocode/v2.00/json.ws'
8
7
  DAILY_LIMIT_EXEEDED_ERROR_CODES = ['8', '17'] # api docs say these two codes are the same error
9
8
  INVALID_API_KEY_ERROR_CODE = '2'
10
9
 
@@ -16,11 +15,11 @@ module Geocoder::Lookup
16
15
  %w(key)
17
16
  end
18
17
 
19
- def query_url(query)
20
- format('%s://%s?%s', protocol, BASE_URL_GEOCODE_V2_00, url_query_string(query))
21
- end
18
+ private # ----------------------------------------------------------------
22
19
 
23
- private
20
+ def base_query_url(query)
21
+ "#{protocol}://services.postcodeanywhere.co.uk/Geocoding/UK/Geocode/v2.00/json.ws?"
22
+ end
24
23
 
25
24
  def results(query)
26
25
  response = fetch_data(query)
@@ -8,15 +8,18 @@ module Geocoder::Lookup
8
8
  end
9
9
 
10
10
  def query_url(query)
11
- str = query.sanitized_text.gsub(/\s/, '')
12
- format('%s://%s/%s', protocol, 'api.postcodes.io/postcodes', str)
11
+ "#{protocol}://api.postcodes.io/postcodes/#{query.sanitized_text.gsub(/\s/, '')}"
13
12
  end
14
13
 
15
14
  def supported_protocols
16
15
  [:https]
17
16
  end
18
17
 
19
- private
18
+ private # ----------------------------------------------------------------
19
+
20
+ def cache_key(query)
21
+ query_url(query)
22
+ end
20
23
 
21
24
  def results(query)
22
25
  response = fetch_data(query)
@@ -11,14 +11,6 @@ module Geocoder::Lookup
11
11
  %w(auti-id auth-token)
12
12
  end
13
13
 
14
- def query_url(query)
15
- if zipcode_only?(query)
16
- "#{protocol}://us-zipcode.api.smartystreets.com/lookup?#{url_query_string(query)}"
17
- else
18
- "#{protocol}://us-street.api.smartystreets.com/street-address?#{url_query_string(query)}"
19
- end
20
- end
21
-
22
14
  # required by API as of 26 March 2015
23
15
  def supported_protocols
24
16
  [:https]
@@ -26,6 +18,14 @@ module Geocoder::Lookup
26
18
 
27
19
  private # ---------------------------------------------------------------
28
20
 
21
+ def base_query_url(query)
22
+ if zipcode_only?(query)
23
+ "#{protocol}://us-zipcode.api.smartystreets.com/lookup?"
24
+ else
25
+ "#{protocol}://us-street.api.smartystreets.com/street-address?"
26
+ end
27
+ end
28
+
29
29
  def zipcode_only?(query)
30
30
  !query.text.is_a?(Array) and query.to_s.strip =~ /\A\d{5}(-\d{4})?\Z/
31
31
  end
@@ -29,6 +29,10 @@ module Geocoder::Lookup
29
29
 
30
30
  private # ---------------------------------------------------------------
31
31
 
32
+ def cache_key(query)
33
+ query_url(query)[/(.*)\?.*/, 1]
34
+ end
35
+
32
36
  def results(query)
33
37
  # don't look up a loopback address, just return the stored result
34
38
  return [reserved_result(query.text)] if query.loopback_ip_address?
@@ -44,7 +48,23 @@ module Geocoder::Lookup
44
48
  end
45
49
 
46
50
  def reserved_result(ip)
47
- {"message" => "Input string is not a valid IP address", "code" => 401}
51
+ {
52
+ "ip" => ip,
53
+ "latitude" => 0,
54
+ "longitude" => 0,
55
+ "city" => "",
56
+ "timezone" => "",
57
+ "asn" => 0,
58
+ "region" => "",
59
+ "offset" => 0,
60
+ "organization" => "",
61
+ "country_code" => "",
62
+ "country_code3" => "",
63
+ "postal_code" => "",
64
+ "continent_code" => "",
65
+ "country" => "",
66
+ "region_code" => ""
67
+ }
48
68
  end
49
69
 
50
70
  def api_key
@@ -12,16 +12,16 @@ module Geocoder::Lookup
12
12
  "http://maps.yandex.ru/?ll=#{coordinates.reverse.join(',')}"
13
13
  end
14
14
 
15
- def query_url(query)
16
- "#{protocol}://geocode-maps.yandex.ru/1.x/?" + url_query_string(query)
17
- end
18
-
19
15
  def supported_protocols
20
16
  [:https]
21
17
  end
22
18
 
23
19
  private # ---------------------------------------------------------------
24
20
 
21
+ def base_query_url(query)
22
+ "#{protocol}://geocode-maps.yandex.ru/1.x/?"
23
+ end
24
+
25
25
  def results(query)
26
26
  return [] unless doc = fetch_data(query)
27
27
  if err = doc['error']
@@ -11,34 +11,34 @@ module Geocoder::Result
11
11
  @data['formatted_address']
12
12
  end
13
13
 
14
- def state
15
- province
16
- end
17
-
18
14
  def province
19
- @data['addressComponent']['province']
15
+ @data['addressComponent'] and @data['addressComponent']['province'] or ""
20
16
  end
21
17
 
18
+ alias_method :state, :province
19
+
22
20
  def city
23
- @data['addressComponent']['city']
21
+ @data['addressComponent'] and @data['addressComponent']['city'] or ""
24
22
  end
25
23
 
26
24
  def district
27
- @data['addressComponent']['district']
25
+ @data['addressComponent'] and @data['addressComponent']['district'] or ""
28
26
  end
29
27
 
30
28
  def street
31
- @data['addressComponent']['street']
29
+ @data['addressComponent'] and @data['addressComponent']['street'] or ""
32
30
  end
33
31
 
34
32
  def street_number
35
- @data['addressComponent']['street_number']
33
+ @data['addressComponent'] and @data['addressComponent']['street_number']
36
34
  end
37
35
 
38
36
  def formatted_address
39
- @data['formatted_address']
37
+ @data['formatted_address'] or ""
40
38
  end
41
39
 
40
+ alias_method :address, :formatted_address
41
+
42
42
  def address_components
43
43
  @data['addressComponent']
44
44
  end
@@ -20,8 +20,20 @@ module Geocoder
20
20
  ##
21
21
  # A string in the given format.
22
22
  #
23
+ # This default implementation dumbly follows the United States address
24
+ # format and will return incorrect results for most countries. Some APIs
25
+ # return properly formatted addresses and those should be funneled
26
+ # through this method.
27
+ #
23
28
  def address(format = :full)
24
- fail
29
+ if state_code.to_s != ""
30
+ s = ", #{state_code}"
31
+ elsif state.to_s != ""
32
+ s = ", #{state}"
33
+ else
34
+ s = ""
35
+ end
36
+ "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
25
37
  end
26
38
 
27
39
  ##
@@ -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
@@ -7,11 +7,6 @@ module Geocoder::Result
7
7
  ['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] }
8
8
  end
9
9
 
10
- def address(format = :full)
11
- s = state_code.to_s == "" ? "" : ", #{state_code}"
12
- "#{city}#{s} #{zip_code}, #{country_name}".sub(/^[ ,]*/, "")
13
- end
14
-
15
10
  def city
16
11
  @data['city']
17
12
  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
@@ -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
@@ -3,10 +3,6 @@ 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
8
  %w[latitude longitude].map do |l|
@@ -59,11 +59,13 @@ module Geocoder::Result
59
59
  private
60
60
 
61
61
  def geolocalized?
62
- try_to_extract('coordinates', geomlonlat).present?
62
+ !!try_to_extract('coordinates', geomlonlat)
63
63
  end
64
64
 
65
- def try_to_extract(key, nullable_hash)
66
- nullable_hash.try(:[], key)
65
+ def try_to_extract(key, hash)
66
+ if hash.is_a?(Hash) and hash.include?(key)
67
+ hash[key]
68
+ end
67
69
  end
68
70
  end
69
71
  end