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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +2 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +0 -1
- data/lib/geocoder/configuration.rb +9 -6
- data/lib/geocoder/lookup.rb +2 -1
- data/lib/geocoder/lookups/base.rb +1 -6
- data/lib/geocoder/lookups/google_places_details.rb +20 -0
- data/lib/geocoder/lookups/google_places_search.rb +20 -3
- data/lib/geocoder/lookups/here.rb +25 -20
- data/lib/geocoder/lookups/twogis.rb +58 -0
- data/lib/geocoder/results/here.rb +20 -25
- data/lib/geocoder/results/twogis.rb +76 -0
- data/lib/geocoder/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a0d33121c080f317bcfcad5c3547491676b1edcef61e33cb3a090e91cccdeee
|
4
|
+
data.tar.gz: 066ff69c5443b18d9f5b4e1af94481b588bf18560050e0da49129b3630f5047b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
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
|
-
#
|
127
|
-
|
128
|
-
|
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|
|
data/lib/geocoder/lookup.rb
CHANGED
@@ -83,13 +83,8 @@ module Geocoder
|
|
83
83
|
# The working Cache object.
|
84
84
|
#
|
85
85
|
def cache
|
86
|
-
if @cache.nil?
|
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
|
-
|
40
|
-
|
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.
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
38
|
-
|
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[:
|
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
|
-
|
55
|
+
at: query.sanitized_text
|
60
56
|
)
|
61
57
|
else
|
62
58
|
super.merge(query_url_here_options(query, false)).merge(
|
63
|
-
|
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[
|
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[
|
18
|
-
[d[
|
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[
|
22
|
+
address_data["street"]
|
23
23
|
end
|
24
24
|
|
25
25
|
def street_number
|
26
|
-
address_data[
|
26
|
+
address_data["houseNumber"]
|
27
27
|
end
|
28
28
|
|
29
29
|
def state
|
30
|
-
|
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[
|
34
|
+
address_data["county"]
|
38
35
|
end
|
39
36
|
|
40
37
|
def postal_code
|
41
|
-
address_data[
|
38
|
+
address_data["postalCode"]
|
42
39
|
end
|
43
40
|
|
44
41
|
def city
|
45
|
-
address_data[
|
42
|
+
address_data["city"]
|
46
43
|
end
|
47
44
|
|
48
45
|
def state_code
|
49
|
-
address_data[
|
46
|
+
address_data["stateCode"]
|
50
47
|
end
|
51
48
|
|
52
49
|
def province_code
|
53
|
-
address_data[
|
50
|
+
address_data["state"]
|
54
51
|
end
|
55
52
|
|
56
53
|
def country
|
57
|
-
|
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[
|
58
|
+
address_data["countryCode"]
|
65
59
|
end
|
66
60
|
|
67
61
|
def viewport
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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[
|
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
|
data/lib/geocoder/version.rb
CHANGED
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.
|
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-
|
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
|