geocoder 1.7.5 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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