geocoder 1.6.3 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -0
  3. data/LICENSE +1 -1
  4. data/README.md +329 -233
  5. data/examples/app_defined_lookup_services.rb +22 -0
  6. data/lib/generators/geocoder/config/templates/initializer.rb +6 -1
  7. data/lib/geocoder/cache.rb +16 -33
  8. data/lib/geocoder/cache_stores/base.rb +40 -0
  9. data/lib/geocoder/cache_stores/generic.rb +35 -0
  10. data/lib/geocoder/cache_stores/redis.rb +34 -0
  11. data/lib/geocoder/configuration.rb +19 -5
  12. data/lib/geocoder/configuration_hash.rb +4 -4
  13. data/lib/geocoder/ip_address.rb +6 -0
  14. data/lib/geocoder/lookup.rb +32 -4
  15. data/lib/geocoder/lookups/abstract_api.rb +46 -0
  16. data/lib/geocoder/lookups/amap.rb +2 -2
  17. data/lib/geocoder/lookups/amazon_location_service.rb +54 -0
  18. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +1 -1
  19. data/lib/geocoder/lookups/base.rb +2 -1
  20. data/lib/geocoder/lookups/bing.rb +1 -1
  21. data/lib/geocoder/lookups/esri.rb +4 -0
  22. data/lib/geocoder/lookups/freegeoip.rb +8 -6
  23. data/lib/geocoder/lookups/geoapify.rb +78 -0
  24. data/lib/geocoder/lookups/geocodio.rb +1 -1
  25. data/lib/geocoder/lookups/geoip2.rb +4 -0
  26. data/lib/geocoder/lookups/geoportail_lu.rb +1 -1
  27. data/lib/geocoder/lookups/google.rb +7 -2
  28. data/lib/geocoder/lookups/google_places_details.rb +26 -12
  29. data/lib/geocoder/lookups/google_places_search.rb +45 -2
  30. data/lib/geocoder/lookups/google_premier.rb +4 -0
  31. data/lib/geocoder/lookups/here.rb +25 -20
  32. data/lib/geocoder/lookups/ip2location.rb +10 -6
  33. data/lib/geocoder/lookups/ipbase.rb +49 -0
  34. data/lib/geocoder/lookups/ipdata_co.rb +1 -1
  35. data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
  36. data/lib/geocoder/lookups/location_iq.rb +5 -1
  37. data/lib/geocoder/lookups/maxmind_local.rb +7 -1
  38. data/lib/geocoder/lookups/melissa_street.rb +41 -0
  39. data/lib/geocoder/lookups/photon.rb +89 -0
  40. data/lib/geocoder/lookups/test.rb +5 -0
  41. data/lib/geocoder/lookups/twogis.rb +58 -0
  42. data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +1 -1
  43. data/lib/geocoder/lookups/yandex.rb +3 -3
  44. data/lib/geocoder/results/abstract_api.rb +146 -0
  45. data/lib/geocoder/results/amazon_location_service.rb +57 -0
  46. data/lib/geocoder/results/ban_data_gouv_fr.rb +26 -1
  47. data/lib/geocoder/results/db_ip_com.rb +1 -1
  48. data/lib/geocoder/results/esri.rb +5 -2
  49. data/lib/geocoder/results/geoapify.rb +179 -0
  50. data/lib/geocoder/results/here.rb +20 -25
  51. data/lib/geocoder/results/ipbase.rb +40 -0
  52. data/lib/geocoder/results/ipqualityscore.rb +54 -0
  53. data/lib/geocoder/results/ipregistry.rb +4 -8
  54. data/lib/geocoder/results/mapbox.rb +10 -4
  55. data/lib/geocoder/results/melissa_street.rb +46 -0
  56. data/lib/geocoder/results/nationaal_georegister_nl.rb +1 -1
  57. data/lib/geocoder/results/nominatim.rb +27 -15
  58. data/lib/geocoder/results/photon.rb +119 -0
  59. data/lib/geocoder/results/twogis.rb +76 -0
  60. data/lib/geocoder/util.rb +29 -0
  61. data/lib/geocoder/version.rb +1 -1
  62. metadata +24 -6
  63. data/examples/autoexpire_cache_dalli.rb +0 -62
  64. data/examples/autoexpire_cache_redis.rb +0 -30
  65. data/lib/hash_recursive_merge.rb +0 -73
@@ -29,7 +29,7 @@ module Geocoder::Lookup
29
29
 
30
30
  def base_query_url(query)
31
31
  path = query.reverse_geocode? ? "reverse" : "geocode"
32
- "#{protocol}://api.geocod.io/v1.3/#{path}?"
32
+ "#{protocol}://api.geocod.io/v1.6/#{path}?"
33
33
  end
34
34
 
35
35
  def query_url_params(query)
@@ -37,6 +37,10 @@ module Geocoder
37
37
  def results(query)
38
38
  return [] unless configuration[:file]
39
39
 
40
+ if @mmdb.respond_to?(:local_ip_alias) && !configuration[:local_ip_alias].nil?
41
+ @mmdb.local_ip_alias = configuration[:local_ip_alias]
42
+ end
43
+
40
44
  result = @mmdb.lookup(query.to_s)
41
45
  result.nil? ? [] : [result]
42
46
  end
@@ -56,7 +56,7 @@ module Geocoder
56
56
  else
57
57
  result = []
58
58
  raise_error(Geocoder::Error) ||
59
- warn("Geportail.lu Geocoding API error")
59
+ Geocoder.log(:warn, "Geportail.lu Geocoding API error")
60
60
  end
61
61
  result
62
62
  end
@@ -44,10 +44,15 @@ module Geocoder::Lookup
44
44
  super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
45
45
  end
46
46
 
47
+ def result_root_attr
48
+ 'results'
49
+ end
50
+
47
51
  def results(query)
48
52
  return [] unless doc = fetch_data(query)
49
- case doc['status']; when "OK" # OK status implies >0 results
50
- return doc['results']
53
+ case doc['status']
54
+ when "OK" # OK status implies >0 results
55
+ return doc[result_root_attr]
51
56
  when "OVER_QUERY_LIMIT"
52
57
  raise_error(Geocoder::OverQueryLimitError) ||
53
58
  Geocoder.log(:warn, "#{name} API error: over query limit.")
@@ -22,26 +22,40 @@ module Geocoder
22
22
  "#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
23
23
  end
24
24
 
25
+ def result_root_attr
26
+ 'result'
27
+ end
28
+
25
29
  def results(query)
26
- return [] unless doc = fetch_data(query)
27
-
28
- case doc["status"]
29
- when "OK"
30
- return [doc["result"]]
31
- when "OVER_QUERY_LIMIT"
32
- raise_error(Geocoder::OverQueryLimitError) || Geocoder.log(:warn, "Google Places Details API error: over query limit.")
33
- when "REQUEST_DENIED"
34
- raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Google Places Details API error: request denied.")
35
- when "INVALID_REQUEST"
36
- raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, "Google Places Details API error: invalid request.")
30
+ result = super(query)
31
+ return [result] unless result.is_a? Array
32
+
33
+ result
34
+ end
35
+
36
+ def fields(query)
37
+ if query.options.has_key?(:fields)
38
+ return format_fields(query.options[:fields])
37
39
  end
38
40
 
39
- []
41
+ if configuration.has_key?(:fields)
42
+ return format_fields(configuration[:fields])
43
+ end
44
+
45
+ nil # use Google Places defaults
46
+ end
47
+
48
+ def format_fields(*fields)
49
+ flattened = fields.flatten.compact
50
+ return if flattened.empty?
51
+
52
+ flattened.join(',')
40
53
  end
41
54
 
42
55
  def query_url_google_params(query)
43
56
  {
44
57
  placeid: query.text,
58
+ fields: fields(query),
45
59
  language: query.language || configuration.language
46
60
  }
47
61
  end
@@ -18,16 +18,59 @@ module Geocoder
18
18
 
19
19
  private
20
20
 
21
+ def result_root_attr
22
+ 'candidates'
23
+ end
24
+
21
25
  def base_query_url(query)
22
- "#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?"
26
+ "#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
23
27
  end
24
28
 
25
29
  def query_url_google_params(query)
26
30
  {
27
- query: query.text,
31
+ input: query.text,
32
+ inputtype: 'textquery',
33
+ fields: fields(query),
34
+ locationbias: locationbias(query),
28
35
  language: query.language || configuration.language
29
36
  }
30
37
  end
38
+
39
+ def fields(query)
40
+ if query.options.has_key?(:fields)
41
+ return format_fields(query.options[:fields])
42
+ end
43
+
44
+ if configuration.has_key?(:fields)
45
+ return format_fields(configuration[:fields])
46
+ end
47
+
48
+ default_fields
49
+ end
50
+
51
+ def default_fields
52
+ legacy = %w[id reference]
53
+ basic = %w[business_status formatted_address geometry icon name
54
+ photos place_id plus_code types]
55
+ contact = %w[opening_hours]
56
+ atmosphere = %W[price_level rating user_ratings_total]
57
+ format_fields(legacy, basic, contact, atmosphere)
58
+ end
59
+
60
+ def format_fields(*fields)
61
+ flattened = fields.flatten.compact
62
+ return if flattened.empty?
63
+
64
+ flattened.join(',')
65
+ end
66
+
67
+ def locationbias(query)
68
+ if query.options.has_key?(:locationbias)
69
+ query.options[:locationbias]
70
+ else
71
+ configuration[:locationbias]
72
+ end
73
+ end
31
74
  end
32
75
  end
33
76
  end
@@ -21,6 +21,10 @@ module Geocoder::Lookup
21
21
 
22
22
  private # ---------------------------------------------------------------
23
23
 
24
+ def result_root_attr
25
+ 'results'
26
+ end
27
+
24
28
  def cache_key(query)
25
29
  "#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
26
30
  end
@@ -19,50 +19,55 @@ module Geocoder::Lookup
19
19
  private # ---------------------------------------------------------------
20
20
 
21
21
  def base_query_url(query)
22
- "#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.ls.hereapi.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
22
+ service = query.reverse_geocode? ? "revgeocode" : "geocode"
23
+
24
+ "#{protocol}://#{service}.search.hereapi.com/v1/#{service}?"
23
25
  end
24
26
 
25
27
  def results(query)
26
- return [] unless doc = fetch_data(query)
27
- return [] unless doc['Response'] && doc['Response']['View']
28
- if r=doc['Response']['View']
29
- return [] if r.nil? || !r.is_a?(Array) || r.empty?
30
- return r.first['Result']
28
+ unless configuration.api_key.is_a?(String)
29
+ api_key_not_string!
30
+ return []
31
31
  end
32
- []
32
+ return [] unless doc = fetch_data(query)
33
+ return [] if doc["items"].nil?
34
+
35
+ doc["items"]
33
36
  end
34
37
 
35
38
  def query_url_here_options(query, reverse_geocode)
36
39
  options = {
37
- gen: 9,
38
- apikey: configuration.api_key,
39
- language: (query.language || configuration.language)
40
+ apiKey: configuration.api_key,
41
+ lang: (query.language || configuration.language)
40
42
  }
41
- if reverse_geocode
42
- options[:mode] = :retrieveAddresses
43
- return options
44
- end
43
+ return options if reverse_geocode
45
44
 
46
45
  unless (country = query.options[:country]).nil?
47
- options[:country] = country
46
+ options[:in] = "countryCode:#{country}"
48
47
  end
49
48
 
50
- unless (mapview = query.options[:bounds]).nil?
51
- options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
52
- end
53
49
  options
54
50
  end
55
51
 
56
52
  def query_url_params(query)
57
53
  if query.reverse_geocode?
58
54
  super.merge(query_url_here_options(query, true)).merge(
59
- prox: query.sanitized_text
55
+ at: query.sanitized_text
60
56
  )
61
57
  else
62
58
  super.merge(query_url_here_options(query, false)).merge(
63
- searchtext: query.sanitized_text
59
+ q: query.sanitized_text
64
60
  )
65
61
  end
66
62
  end
63
+
64
+ def api_key_not_string!
65
+ msg = <<~MSG
66
+ API key for HERE Geocoding and Search API should be a string.
67
+ For more info on how to obtain it, please see https://developer.here.com/documentation/identity-access-management/dev_guide/topics/plat-using-apikeys.html
68
+ MSG
69
+
70
+ raise_error(Geocoder::ConfigurationError, msg) || Geocoder.log(:warn, msg)
71
+ end
67
72
  end
68
73
  end
@@ -8,6 +8,10 @@ module Geocoder::Lookup
8
8
  "IP2LocationApi"
9
9
  end
10
10
 
11
+ def required_api_key_parts
12
+ ['key']
13
+ end
14
+
11
15
  def supported_protocols
12
16
  [:http, :https]
13
17
  end
@@ -15,15 +19,15 @@ module Geocoder::Lookup
15
19
  private # ----------------------------------------------------------------
16
20
 
17
21
  def base_query_url(query)
18
- "#{protocol}://api.ip2location.com/?"
22
+ "#{protocol}://api.ip2location.com/v2/?"
19
23
  end
20
24
 
21
25
  def query_url_params(query)
22
- params = super
23
- if configuration.has_key?(:package)
24
- params.merge!(package: configuration[:package])
25
- end
26
- params
26
+ super.merge(
27
+ key: configuration.api_key,
28
+ ip: query.sanitized_text,
29
+ package: configuration[:package],
30
+ )
27
31
  end
28
32
 
29
33
  def results(query)
@@ -0,0 +1,49 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/ipbase'
3
+
4
+ module Geocoder::Lookup
5
+ class Ipbase < Base
6
+
7
+ def name
8
+ "ipbase.com"
9
+ end
10
+
11
+ def supported_protocols
12
+ [:https]
13
+ end
14
+
15
+ private # ---------------------------------------------------------------
16
+
17
+ def base_query_url(query)
18
+ "https://api.ipbase.com/v2/info?"
19
+ end
20
+
21
+ def query_url_params(query)
22
+ {
23
+ :ip => query.sanitized_text,
24
+ :apikey => configuration.api_key
25
+ }
26
+ end
27
+
28
+ def results(query)
29
+ # don't look up a loopback or private address, just return the stored result
30
+ return [reserved_result(query.text)] if query.internal_ip_address?
31
+ doc = fetch_data(query) || {}
32
+ doc.fetch("data", {})["location"] ? [doc] : []
33
+ end
34
+
35
+ def reserved_result(ip)
36
+ {
37
+ "data" => {
38
+ "ip" => ip,
39
+ "location" => {
40
+ "city" => { "name" => "" },
41
+ "country" => { "alpha2" => "RD", "name" => "Reserved" },
42
+ "region" => { "alpha2" => "", "name" => "" },
43
+ "zip" => ""
44
+ }
45
+ }
46
+ }
47
+ end
48
+ end
49
+ end
@@ -47,7 +47,7 @@ module Geocoder::Lookup
47
47
  end
48
48
 
49
49
  def host
50
- "api.ipdata.co"
50
+ configuration[:host] || "api.ipdata.co"
51
51
  end
52
52
 
53
53
  def check_response_for_errors!(response)
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'geocoder/lookups/base'
4
+ require 'geocoder/results/ipqualityscore'
5
+
6
+ module Geocoder::Lookup
7
+ class Ipqualityscore < Base
8
+
9
+ def name
10
+ "IPQualityScore"
11
+ end
12
+
13
+ def required_api_key_parts
14
+ ['api_key']
15
+ end
16
+
17
+ private # ---------------------------------------------------------------
18
+
19
+ def base_query_url(query)
20
+ "#{protocol}://ipqualityscore.com/api/json/ip/#{configuration.api_key}/#{query.sanitized_text}?"
21
+ end
22
+
23
+ def valid_response?(response)
24
+ if (json = parse_json(response.body))
25
+ success = json['success']
26
+ end
27
+ super && success == true
28
+ end
29
+
30
+ def results(query, reverse = false)
31
+ return [] unless doc = fetch_data(query)
32
+
33
+ return [doc] if doc['success']
34
+
35
+ case doc['message']
36
+ when /invalid (.*) key/i
37
+ raise_error Geocoder::InvalidApiKey ||
38
+ Geocoder.log(:warn, "#{name} API error: invalid api key.")
39
+ when /insufficient credits/, /exceeded your request quota/
40
+ raise_error Geocoder::OverQueryLimitError ||
41
+ Geocoder.log(:warn, "#{name} API error: query limit exceeded.")
42
+ when /invalid (.*) address/i
43
+ raise_error Geocoder::InvalidRequest ||
44
+ Geocoder.log(:warn, "#{name} API error: invalid request.")
45
+ end
46
+
47
+ [doc]
48
+ end
49
+ end
50
+ end
@@ -11,6 +11,10 @@ module Geocoder::Lookup
11
11
  ["api_key"]
12
12
  end
13
13
 
14
+ def supported_protocols
15
+ [:https]
16
+ end
17
+
14
18
  private # ----------------------------------------------------------------
15
19
 
16
20
  def base_query_url(query)
@@ -25,7 +29,7 @@ module Geocoder::Lookup
25
29
  end
26
30
 
27
31
  def configured_host
28
- configuration[:host] || "locationiq.org"
32
+ configuration[:host] || "us1.locationiq.com"
29
33
  end
30
34
 
31
35
  def results(query)
@@ -30,7 +30,13 @@ module Geocoder::Lookup
30
30
  def results(query)
31
31
  if configuration[:file]
32
32
  geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP
33
- result = geoip_class.new(configuration[:file]).city(query.to_s)
33
+ geoip_instance = geoip_class.new(configuration[:file])
34
+ result =
35
+ if configuration[:package] == :country
36
+ geoip_instance.country(query.to_s)
37
+ else
38
+ geoip_instance.city(query.to_s)
39
+ end
34
40
  result.nil? ? [] : [encode_hash(result.to_hash)]
35
41
  elsif configuration[:package] == :city
36
42
  addr = IPAddr.new(query.text).to_i
@@ -0,0 +1,41 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/melissa_street"
3
+
4
+ module Geocoder::Lookup
5
+ class MelissaStreet < Base
6
+
7
+ def name
8
+ "MelissaStreet"
9
+ end
10
+
11
+ def results(query)
12
+ return [] unless doc = fetch_data(query)
13
+
14
+ if doc["TransmissionResults"] == "GE05"
15
+ raise_error(Geocoder::InvalidApiKey) ||
16
+ Geocoder.log(:warn, "Melissa service error: invalid API key.")
17
+ end
18
+
19
+ return doc["Records"]
20
+ end
21
+
22
+ private # ---------------------------------------------------------------
23
+
24
+ def base_query_url(query)
25
+ "#{protocol}://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress?"
26
+ end
27
+
28
+ def query_url_params(query)
29
+ params = {
30
+ id: configuration.api_key,
31
+ format: "JSON",
32
+ a1: query.sanitized_text,
33
+ loc: query.options[:city],
34
+ admarea: query.options[:state],
35
+ postal: query.options[:postal],
36
+ ctry: query.options[:country]
37
+ }
38
+ params.merge(super)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,89 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/photon'
3
+
4
+ module Geocoder::Lookup
5
+ class Photon < Base
6
+ def name
7
+ 'Photon'
8
+ end
9
+
10
+ private # ---------------------------------------------------------------
11
+
12
+ def supported_protocols
13
+ [:https]
14
+ end
15
+
16
+ def base_query_url(query)
17
+ host = configuration[:host] || 'photon.komoot.io'
18
+ method = query.reverse_geocode? ? 'reverse' : 'api'
19
+ "#{protocol}://#{host}/#{method}?"
20
+ end
21
+
22
+ def results(query)
23
+ return [] unless (doc = fetch_data(query))
24
+ return [] unless doc['type'] == 'FeatureCollection'
25
+ return [] unless doc['features'] || doc['features'].present?
26
+
27
+ doc['features']
28
+ end
29
+
30
+ def query_url_params(query)
31
+ lang = query.language || configuration.language
32
+ params = { lang: lang, limit: query.options[:limit] }
33
+
34
+ if query.reverse_geocode?
35
+ params.merge!(query_url_params_reverse(query))
36
+ else
37
+ params.merge!(query_url_params_coordinates(query))
38
+ end
39
+
40
+ params.merge!(super)
41
+ end
42
+
43
+ def query_url_params_coordinates(query)
44
+ params = { q: query.sanitized_text }
45
+
46
+ if (bias = query.options[:bias])
47
+ params.merge!(lat: bias[:latitude], lon: bias[:longitude], location_bias_scale: bias[:scale])
48
+ end
49
+
50
+ if (filter = query_url_params_coordinates_filter(query))
51
+ params.merge!(filter)
52
+ end
53
+
54
+ params
55
+ end
56
+
57
+ def query_url_params_coordinates_filter(query)
58
+ filter = query.options[:filter]
59
+ return unless filter
60
+
61
+ bbox = filter[:bbox]
62
+ {
63
+ bbox: bbox.is_a?(Array) ? bbox.join(',') : bbox,
64
+ osm_tag: filter[:osm_tag]
65
+ }
66
+ end
67
+
68
+ def query_url_params_reverse(query)
69
+ params = { lat: query.coordinates[0], lon: query.coordinates[1], radius: query.options[:radius] }
70
+
71
+ if (dsort = query.options[:distance_sort])
72
+ params[:distance_sort] = dsort ? 'true' : 'false'
73
+ end
74
+
75
+ if (filter = query_url_params_reverse_filter(query))
76
+ params.merge!(filter)
77
+ end
78
+
79
+ params
80
+ end
81
+
82
+ def query_url_params_reverse_filter(query)
83
+ filter = query.options[:filter]
84
+ return unless filter
85
+
86
+ { query_string_filter: filter[:string] }
87
+ end
88
+ end
89
+ end
@@ -18,6 +18,7 @@ module Geocoder
18
18
  end
19
19
 
20
20
  def self.read_stub(query_text)
21
+ @default_stub ||= nil
21
22
  stubs.fetch(query_text) {
22
23
  return @default_stub unless @default_stub.nil?
23
24
  raise ArgumentError, "unknown stub request #{query_text}"
@@ -28,6 +29,10 @@ module Geocoder
28
29
  @stubs ||= {}
29
30
  end
30
31
 
32
+ def self.delete_stub(query_text)
33
+ stubs.delete(query_text)
34
+ end
35
+
31
36
  def self.reset
32
37
  @stubs = {}
33
38
  @default_stub = nil
@@ -0,0 +1,58 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/twogis"
3
+
4
+ module Geocoder::Lookup
5
+ class Twogis < Base
6
+
7
+ def name
8
+ "2gis"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["key"]
13
+ end
14
+
15
+ def map_link_url(coordinates)
16
+ "https://2gis.ru/?m=#{coordinates.join(',')}"
17
+ end
18
+
19
+ def supported_protocols
20
+ [:https]
21
+ end
22
+
23
+ private # ---------------------------------------------------------------
24
+
25
+ def base_query_url(query)
26
+ "#{protocol}://catalog.api.2gis.com/3.0/items/geocode?"
27
+ end
28
+
29
+ def results(query)
30
+ return [] unless doc = fetch_data(query)
31
+ if doc['meta'] && doc['meta']['error']
32
+ Geocoder.log(:warn, "2gis Geocoding API error: #{doc['meta']["code"]} (#{doc['meta']['error']["message"]}).")
33
+ return []
34
+ end
35
+ if doc['result'] && doc = doc['result']['items']
36
+ return doc.to_a
37
+ else
38
+ Geocoder.log(:warn, "2gis Geocoding API error: unexpected response format.")
39
+ return []
40
+ end
41
+ end
42
+
43
+ def query_url_params(query)
44
+ if query.reverse_geocode?
45
+ q = query.coordinates.reverse.join(",")
46
+ else
47
+ q = query.sanitized_text
48
+ end
49
+ params = {
50
+ :q => q,
51
+ :lang => "#{query.language || configuration.language}",
52
+ :key => configuration.api_key,
53
+ :fields => 'items.street,items.adm_div,items.full_address_name,items.point,items.geometry.centroid'
54
+ }
55
+ params.merge(super)
56
+ end
57
+ end
58
+ end
@@ -13,7 +13,7 @@ module Geocoder::Lookup
13
13
  end
14
14
 
15
15
  def base_query_url(query)
16
- "#{protocol}://api.ordnancesurvey.co.uk/opennames/v1/find?"
16
+ "#{protocol}://api.os.uk/search/names/v1/find?"
17
17
  end
18
18
 
19
19
  def required_api_key_parts
@@ -24,11 +24,11 @@ module Geocoder::Lookup
24
24
 
25
25
  def results(query)
26
26
  return [] unless doc = fetch_data(query)
27
- if err = doc['error']
28
- if err["status"] == 401 and err["message"] == "invalid key"
27
+ if [400, 403].include? doc['statusCode']
28
+ if doc['statusCode'] == 403 and doc['message'] == 'Invalid key'
29
29
  raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
30
30
  else
31
- Geocoder.log(:warn, "Yandex Geocoding API error: #{err['status']} (#{err['message']}).")
31
+ Geocoder.log(:warn, "Yandex Geocoding API error: #{doc['statusCode']} (#{doc['message']}).")
32
32
  end
33
33
  return []
34
34
  end