geocoder 1.7.5 → 1.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5063f6ec31c36d023439cdb255c76f62e9107da4d3bd42667a0f8a1df12919fd
4
- data.tar.gz: d260cd1d770947fa7415989c63404bb0f0e179eee7a0e0e09c3e5c56b019dec2
3
+ metadata.gz: 3a0d33121c080f317bcfcad5c3547491676b1edcef61e33cb3a090e91cccdeee
4
+ data.tar.gz: 066ff69c5443b18d9f5b4e1af94481b588bf18560050e0da49129b3630f5047b
5
5
  SHA512:
6
- metadata.gz: dd798ea9317b6cbdc51b521c60558002fc4263adb52fd2de8277e834a03a04561cedc070e2d08f4fe9ebd688771a8f6440a9c9288a83b6d3412d3d100714a99f
7
- data.tar.gz: d262213ca0f637847d571d81054365e969c6eb6b3444e6064a538928a0fb673c5e7c315bc0708758c33e107d46bf38a642f91bccb574273e0c784c77cf8562ad
6
+ metadata.gz: 3e47b46a3c299023708b9a2444315d0e9b2788cf682e7e72e1d2ae8d0be40c9d6b7cf25793f20c946f6941662c6512d86bea29bd48e81485546facf00f9cdea3
7
+ data.tar.gz: 0bd121ae2aa3b8e2232e343d70557a7c9201f06dc47a8ae59d5b28e8610c8627ed6beefb251020537979de472e35d0174ab5fad20994e1414914a28f3d91ba1c
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@ Changelog
3
3
 
4
4
  Major changes to Geocoder for each release. Please see the Git log for complete list of changes.
5
5
 
6
+ 1.8.0 (2022 May 17)
7
+ -------------------
8
+ * Add support for 2GIS lookup (thanks github.com/ggrikgg).
9
+ * Change cache configuration structure and add an expiration option. Cache prefix is now set via {cache_options: {prefix: ...}} instead of {cache_prefix: ...}. See README for details.
10
+ * Add `:fields` parameter for :google_places_details and :google_places_search lookups. If you haven't been requesting specific fields, you may start getting different data (defaults are now the APIs' defaults). See for details: https://github.com/alexreisner/geocoder/pull/1572 (thanks github.com/czlee).
11
+ * Update :here lookup to use API version 7. Query options are different, API key must be a string (not an array). See API docs at https://developer.here.com/documentation/geocoding-search-api/api-reference-swagger.html (thanks github.com/Pritilender).
12
+
6
13
  1.7.5 (2022 Mar 14)
7
14
  -------------------
8
15
  * Avoid lookup naming collisions in some environments.
data/README.md CHANGED
@@ -246,11 +246,10 @@ Geocoder.configure(
246
246
  units: :km,
247
247
 
248
248
  # caching (see Caching section below for details):
249
- # warning: `cache_prefix` is deprecated, use `cache_options` instead
250
249
  cache: Redis.new,
251
250
  cache_options: {
252
- expiration: 2.days, # Redis ttl
253
- prefix: "..."
251
+ expiration: 1.day, # Defaults to `nil`
252
+ prefix: "another_key:" # Defaults to `geocoder:`
254
253
  }
255
254
  )
256
255
  ```
@@ -9,7 +9,6 @@ Geocoder.configure(
9
9
  # https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
10
10
  # api_key: nil, # API key for geocoding service
11
11
  # cache: nil, # cache object (must respond to #[], #[]=, and #del)
12
- # cache_prefix: 'geocoder:', # DEPRECATED, please use cache_options[:prefix] instead
13
12
 
14
13
  # Exceptions that should not be rescued by default
15
14
  # (if you want to implement custom error handling);
@@ -62,7 +62,6 @@ module Geocoder
62
62
  :https_proxy,
63
63
  :api_key,
64
64
  :cache,
65
- :cache_prefix,
66
65
  :always_raise,
67
66
  :units,
68
67
  :distances,
@@ -108,8 +107,6 @@ module Geocoder
108
107
  @data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
109
108
  @data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
110
109
  @data[:api_key] = nil # API key for geocoding service
111
- @data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
112
- @data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
113
110
  @data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
114
111
  @data[:logger] = :kernel # :kernel or Logger instance
115
112
  @data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
@@ -123,9 +120,15 @@ module Geocoder
123
120
  @data[:units] = :mi # :mi or :km
124
121
  @data[:distances] = :linear # :linear or :spherical
125
122
 
126
- # explicit cache service options
127
- @data[:cache_options] ||= {}
128
- @data[:cache_options][:prefix] = "geocoder:"
123
+ # Set the default values for the caching mechanism
124
+ # By default, the cache keys will not expire as IP addresses and phyiscal
125
+ # addresses will rarely change.
126
+ @data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
127
+ @data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
128
+ @data[:cache_options] = {
129
+ prefix: 'geocoder:',
130
+ expiration: nil
131
+ }
129
132
  end
130
133
 
131
134
  instance_eval(OPTIONS.map do |option|
@@ -65,7 +65,8 @@ module Geocoder
65
65
  :melissa_street,
66
66
  :amazon_location_service,
67
67
  :geoapify,
68
- :photon
68
+ :photon,
69
+ :twogis
69
70
  ]
70
71
  end
71
72
 
@@ -83,13 +83,8 @@ module Geocoder
83
83
  # The working Cache object.
84
84
  #
85
85
  def cache
86
- if @cache.nil? && (store = configuration.cache)
86
+ if @cache.nil? and store = configuration.cache
87
87
  cache_options = configuration.cache_options
88
- cache_prefix = (configuration.cache_prefix rescue false)
89
- if cache_prefix
90
- cache_options[:prefix] ||= configuration.cache_prefix
91
- warn '[Geocoder] cache_prefix is deprecated, please change to cache_options.prefix instead'
92
- end
93
88
  @cache = Cache.new(store, cache_options)
94
89
  end
95
90
  @cache
@@ -33,9 +33,29 @@ module Geocoder
33
33
  result
34
34
  end
35
35
 
36
+ def fields(query)
37
+ if query.options.has_key?(:fields)
38
+ return format_fields(query.options[:fields])
39
+ end
40
+
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(',')
53
+ end
54
+
36
55
  def query_url_google_params(query)
37
56
  {
38
57
  placeid: query.text,
58
+ fields: fields(query),
39
59
  language: query.language || configuration.language
40
60
  }
41
61
  end
@@ -31,13 +31,19 @@ module Geocoder
31
31
  input: query.text,
32
32
  inputtype: 'textquery',
33
33
  fields: fields(query),
34
+ locationbias: locationbias(query),
34
35
  language: query.language || configuration.language
35
36
  }
36
37
  end
37
38
 
38
39
  def fields(query)
39
- query_fields = query.options[:fields]
40
- return format_fields(query_fields) if query_fields
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
41
47
 
42
48
  default_fields
43
49
  end
@@ -52,7 +58,18 @@ module Geocoder
52
58
  end
53
59
 
54
60
  def format_fields(*fields)
55
- fields.flatten.join(',')
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
56
73
  end
57
74
  end
58
75
  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
@@ -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
@@ -7,76 +7,71 @@ module Geocoder::Result
7
7
  # A string in the given format.
8
8
  #
9
9
  def address(format = :full)
10
- address_data['Label']
10
+ address_data["label"]
11
11
  end
12
12
 
13
13
  ##
14
14
  # A two-element array: [lat, lon].
15
15
  #
16
16
  def coordinates
17
- fail unless d = @data['Location']['DisplayPosition']
18
- [d['Latitude'].to_f, d['Longitude'].to_f]
17
+ fail unless d = @data["position"]
18
+ [d["lat"].to_f, d["lng"].to_f]
19
19
  end
20
20
 
21
21
  def route
22
- address_data['Street']
22
+ address_data["street"]
23
23
  end
24
24
 
25
25
  def street_number
26
- address_data['HouseNumber']
26
+ address_data["houseNumber"]
27
27
  end
28
28
 
29
29
  def state
30
- fail unless d = address_data['AdditionalData']
31
- if v = d.find{|ad| ad['key']=='StateName'}
32
- return v['value']
33
- end
30
+ address_data["state"]
34
31
  end
35
32
 
36
33
  def province
37
- address_data['County']
34
+ address_data["county"]
38
35
  end
39
36
 
40
37
  def postal_code
41
- address_data['PostalCode']
38
+ address_data["postalCode"]
42
39
  end
43
40
 
44
41
  def city
45
- address_data['City']
42
+ address_data["city"]
46
43
  end
47
44
 
48
45
  def state_code
49
- address_data['State']
46
+ address_data["stateCode"]
50
47
  end
51
48
 
52
49
  def province_code
53
- address_data['State']
50
+ address_data["state"]
54
51
  end
55
52
 
56
53
  def country
57
- fail unless d = address_data['AdditionalData']
58
- if v = d.find{|ad| ad['key']=='CountryName'}
59
- return v['value']
60
- end
54
+ address_data["countryName"]
61
55
  end
62
56
 
63
57
  def country_code
64
- address_data['Country']
58
+ address_data["countryCode"]
65
59
  end
66
60
 
67
61
  def viewport
68
- map_view = data['Location']['MapView'] || fail
69
- south = map_view['BottomRight']['Latitude']
70
- west = map_view['TopLeft']['Longitude']
71
- north = map_view['TopLeft']['Latitude']
72
- east = map_view['BottomRight']['Longitude']
62
+ return [] if data["resultType"] == "place"
63
+ map_view = data["mapView"]
64
+ south = map_view["south"]
65
+ west = map_view["west"]
66
+ north = map_view["north"]
67
+ east = map_view["east"]
73
68
  [south, west, north, east]
74
69
  end
75
70
 
76
71
  private # ----------------------------------------------------------------
77
72
 
78
73
  def address_data
79
- @data['Location']['Address'] || fail
74
+ @data["address"] || fail
80
75
  end
81
76
  end
82
77
  end
@@ -0,0 +1,76 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Twogis < Base
5
+ def coordinates
6
+ ['lat', 'lon'].map{ |i| @data['point'][i] } if @data['point']
7
+ end
8
+
9
+ def address(_format = :full)
10
+ @data['full_address_name'] || ''
11
+ end
12
+
13
+ def city
14
+ return '' unless @data['adm_div']
15
+ @data['adm_div'].select{|u| u["type"] == "city"}.first.try(:[], 'name') || ''
16
+ end
17
+
18
+ def region
19
+ return '' unless @data['adm_div']
20
+ @data['adm_div'].select{|u| u["type"] == "region"}.first.try(:[], 'name') || ''
21
+ end
22
+
23
+ def country
24
+ return '' unless @data['adm_div']
25
+ @data['adm_div'].select{|u| u["type"] == "country"}.first.try(:[], 'name') || ''
26
+ end
27
+
28
+ def district
29
+ return '' unless @data['adm_div']
30
+ @data['adm_div'].select{|u| u["type"] == "district"}.first.try(:[], 'name') || ''
31
+ end
32
+
33
+ def district_area
34
+ return '' unless @data['adm_div']
35
+ @data['adm_div'].select{|u| u["type"] == "district_area"}.first.try(:[], 'name') || ''
36
+ end
37
+
38
+ def street_address
39
+ @data['address_name'] || ''
40
+ end
41
+
42
+ def street
43
+ return '' unless @data['address_name']
44
+ @data['address_name'].split(', ').first
45
+ end
46
+
47
+ def street_number
48
+ return '' unless @data['address_name']
49
+ @data['address_name'].split(', ')[1] || ''
50
+ end
51
+
52
+ def type
53
+ @data['type'] || ''
54
+ end
55
+
56
+ def purpose_name
57
+ @data['purpose_name'] || ''
58
+ end
59
+
60
+ def building_name
61
+ @data['building_name'] || ''
62
+ end
63
+
64
+ def subtype
65
+ @data['subtype'] || ''
66
+ end
67
+
68
+ def subtype_specification
69
+ @data['subtype_specification'] || ''
70
+ end
71
+
72
+ def name
73
+ @data['name'] || ''
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.7.5"
2
+ VERSION = "1.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.5
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reisner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-14 00:00:00.000000000 Z
11
+ date: 2022-05-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Object geocoding (by street or IP address), reverse geocoding (coordinates
14
14
  to street address), distance queries for ActiveRecord and Mongoid, result caching,
@@ -103,6 +103,7 @@ files:
103
103
  - lib/geocoder/lookups/telize.rb
104
104
  - lib/geocoder/lookups/tencent.rb
105
105
  - lib/geocoder/lookups/test.rb
106
+ - lib/geocoder/lookups/twogis.rb
106
107
  - lib/geocoder/lookups/uk_ordnance_survey_names.rb
107
108
  - lib/geocoder/lookups/yandex.rb
108
109
  - lib/geocoder/models/active_record.rb
@@ -165,6 +166,7 @@ files:
165
166
  - lib/geocoder/results/telize.rb
166
167
  - lib/geocoder/results/tencent.rb
167
168
  - lib/geocoder/results/test.rb
169
+ - lib/geocoder/results/twogis.rb
168
170
  - lib/geocoder/results/uk_ordnance_survey_names.rb
169
171
  - lib/geocoder/results/yandex.rb
170
172
  - lib/geocoder/sql.rb