geocoder 1.7.1 → 1.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +9 -3
- data/examples/app_defined_lookup_services.rb +22 -0
- data/lib/geocoder/cache_stores/generic.rb +3 -1
- data/lib/geocoder/cache_stores/redis.rb +3 -1
- data/lib/geocoder/configuration.rb +4 -3
- data/lib/geocoder/lookup.rb +14 -2
- data/lib/geocoder/lookups/freegeoip.rb +8 -6
- data/lib/geocoder/lookups/location_iq.rb +5 -1
- data/lib/geocoder/results/nominatim.rb +24 -16
- data/lib/geocoder/version.rb +1 -1
- metadata +3 -4
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e298d39c596857e28539779ed539ad5f9995368f3021f6541deb53d478b80a0a
|
4
|
+
data.tar.gz: ed9831a260f47cba9d9bc9a069c6e04362621e3cb72175c56332973196420679
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7801cdd189f6ae89c512b42ce57d4a34a37a0750596f2df4f299693be2318ab2e3d0f55970ec0f9f14435c05d86c56bb3989f28748f972aa8d8fc9409adf927
|
7
|
+
data.tar.gz: cc35bb7280bcb43bb9c082dfac6ca5dc395fe3690080d809054761cf147a943868d05ce4f8ce9e4a31b2c67e019e483abcb7c114c7ca711b9c9961e523e57425
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,19 @@ 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.7.4 (2022 Mar 14)
|
7
|
+
-------------------
|
8
|
+
* Add ability to use app-defined lookups (thanks github.com/januszm).
|
9
|
+
* Updates to LocationIQ and FreeGeoIP lookups.
|
10
|
+
|
11
|
+
1.7.3 (2022 Jan 17)
|
12
|
+
-------------------
|
13
|
+
* Get rid of unnecessary cache_prefix deprecation warnings.
|
14
|
+
|
15
|
+
1.7.2 (2022 Jan 2)
|
16
|
+
-------------------
|
17
|
+
* Fix uninitialized constant error (occurring on some systems with v1.7.1).
|
18
|
+
|
6
19
|
1.7.1 (2022 Jan 1)
|
7
20
|
-------------------
|
8
21
|
* Various bugfixes and refactorings.
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@ Compatibility:
|
|
20
20
|
|
21
21
|
* Ruby versions: 2.1+, and JRuby.
|
22
22
|
* Databases: MySQL, PostgreSQL, SQLite, and MongoDB.
|
23
|
-
* Rails: 5.x and
|
23
|
+
* Rails: 5.x, 6.x, and 7.x.
|
24
24
|
* Works outside of Rails with the `json` (for MRI) or `json_pure` (for JRuby) gem.
|
25
25
|
|
26
26
|
|
@@ -78,7 +78,7 @@ results.first.address
|
|
78
78
|
# => "Hôtel de Ville, 75004 Paris, France"
|
79
79
|
```
|
80
80
|
|
81
|
-
You can also look up the location of an IP
|
81
|
+
You can also look up the location of an IP address:
|
82
82
|
|
83
83
|
```ruby
|
84
84
|
results = Geocoder.search("172.56.21.89")
|
@@ -350,10 +350,16 @@ This example uses Redis, but the cache store can be any object that supports the
|
|
350
350
|
|
351
351
|
Even a plain Ruby hash will work, though it's not a great choice (cleared out when app is restarted, not shared between app instances, etc).
|
352
352
|
|
353
|
+
When using Rails use the Generic cache store as an adapter around `Rails.cache`:
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
Geocoder.configure(cache: Geocoder::CacheStore::Generic.new(Rails.cache, {}))
|
357
|
+
```
|
358
|
+
|
353
359
|
You can also set a custom prefix to be used for cache keys:
|
354
360
|
|
355
361
|
```ruby
|
356
|
-
Geocoder.configure(
|
362
|
+
Geocoder.configure(cache_options: { prefix: "..." })
|
357
363
|
```
|
358
364
|
|
359
365
|
By default the prefix is `geocoder:`
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# To extend the Geocoder with additional lookups that come from the application,
|
2
|
+
# not shipped with the gem, define a "child" lookup in your application, based on existing one.
|
3
|
+
# This is required because the Geocoder::Configuration is a Singleton and stores one api key per lookup.
|
4
|
+
|
5
|
+
# in app/libs/geocoder/lookup/my_preciousss.rb
|
6
|
+
module Geocoder::Lookup
|
7
|
+
class MyPreciousss < Google
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Update Geocoder's street_services on initialize:
|
12
|
+
# config/initializers/geocoder.rb
|
13
|
+
Geocoder::Lookup.street_services << :my_preciousss
|
14
|
+
|
15
|
+
# Override the configuration when necessary (e.g. provide separate Google API key for the account):
|
16
|
+
Geocoder.configure(my_preciousss: { api_key: 'abcdef' })
|
17
|
+
|
18
|
+
# Lastly, search using your custom lookup service/api keys
|
19
|
+
Geocoder.search("Paris", lookup: :my_preciousss)
|
20
|
+
|
21
|
+
# This is useful when we have groups of users in the application who use Google paid services
|
22
|
+
# and we want to properly separate them and allow using individual API KEYS or timeouts.
|
@@ -108,8 +108,8 @@ module Geocoder
|
|
108
108
|
@data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
|
109
109
|
@data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
|
110
110
|
@data[:api_key] = nil # API key for geocoding service
|
111
|
-
@data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
|
112
|
-
@data[:cache_prefix] =
|
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
113
|
@data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
|
114
114
|
@data[:logger] = :kernel # :kernel or Logger instance
|
115
115
|
@data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
|
@@ -124,7 +124,8 @@ module Geocoder
|
|
124
124
|
@data[:distances] = :linear # :linear or :spherical
|
125
125
|
|
126
126
|
# explicit cache service options
|
127
|
-
@data[:cache_options]
|
127
|
+
@data[:cache_options] ||= {}
|
128
|
+
@data[:cache_options][:prefix] = "geocoder:"
|
128
129
|
end
|
129
130
|
|
130
131
|
instance_eval(OPTIONS.map do |option|
|
data/lib/geocoder/lookup.rb
CHANGED
@@ -117,8 +117,7 @@ module Geocoder
|
|
117
117
|
def spawn(name)
|
118
118
|
if all_services.include?(name)
|
119
119
|
name = name.to_s
|
120
|
-
|
121
|
-
Geocoder::Lookup.const_get(classify_name(name)).new
|
120
|
+
instantiate_lookup(name)
|
122
121
|
else
|
123
122
|
valids = all_services.map(&:inspect).join(", ")
|
124
123
|
raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
|
@@ -132,5 +131,18 @@ module Geocoder
|
|
132
131
|
def classify_name(filename)
|
133
132
|
filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
|
134
133
|
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Safely instantiate Lookup
|
137
|
+
#
|
138
|
+
def instantiate_lookup(name)
|
139
|
+
class_name = classify_name(name)
|
140
|
+
begin
|
141
|
+
Geocoder::Lookup.const_get(class_name)
|
142
|
+
rescue NameError
|
143
|
+
require "geocoder/lookups/#{name}"
|
144
|
+
end
|
145
|
+
Geocoder::Lookup.const_get(class_name).new
|
146
|
+
end
|
135
147
|
end
|
136
148
|
end
|
@@ -17,14 +17,16 @@ module Geocoder::Lookup
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def query_url(query)
|
21
|
-
"#{protocol}://#{host}/json/#{query.sanitized_text}"
|
22
|
-
end
|
23
|
-
|
24
20
|
private # ---------------------------------------------------------------
|
25
21
|
|
26
|
-
def
|
27
|
-
|
22
|
+
def base_query_url(query)
|
23
|
+
"#{protocol}://#{host}/json/#{query.sanitized_text}?"
|
24
|
+
end
|
25
|
+
|
26
|
+
def query_url_params(query)
|
27
|
+
{
|
28
|
+
:apikey => configuration.api_key
|
29
|
+
}.merge(super)
|
28
30
|
end
|
29
31
|
|
30
32
|
def parse_raw_data(raw_data)
|
@@ -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.
|
32
|
+
configuration[:host] || "us1.locationiq.com"
|
29
33
|
end
|
30
34
|
|
31
35
|
def results(query)
|
@@ -4,12 +4,12 @@ module Geocoder::Result
|
|
4
4
|
class Nominatim < Base
|
5
5
|
|
6
6
|
def poi
|
7
|
-
return
|
7
|
+
return address_data[place_type] if address_data.key?(place_type)
|
8
8
|
return nil
|
9
9
|
end
|
10
10
|
|
11
11
|
def house_number
|
12
|
-
|
12
|
+
address_data['house_number']
|
13
13
|
end
|
14
14
|
|
15
15
|
def address
|
@@ -18,69 +18,71 @@ module Geocoder::Result
|
|
18
18
|
|
19
19
|
def street
|
20
20
|
%w[road pedestrian highway].each do |key|
|
21
|
-
return
|
21
|
+
return address_data[key] if address_data.key?(key)
|
22
22
|
end
|
23
23
|
return nil
|
24
24
|
end
|
25
25
|
|
26
26
|
def city
|
27
27
|
%w[city town village hamlet].each do |key|
|
28
|
-
return
|
28
|
+
return address_data[key] if address_data.key?(key)
|
29
29
|
end
|
30
30
|
return nil
|
31
31
|
end
|
32
32
|
|
33
33
|
def village
|
34
|
-
|
34
|
+
address_data['village']
|
35
35
|
end
|
36
36
|
|
37
37
|
def town
|
38
|
-
|
38
|
+
address_data['town']
|
39
39
|
end
|
40
40
|
|
41
41
|
def state
|
42
|
-
|
42
|
+
address_data['state']
|
43
43
|
end
|
44
44
|
|
45
45
|
alias_method :state_code, :state
|
46
46
|
|
47
47
|
def postal_code
|
48
|
-
|
48
|
+
address_data['postcode']
|
49
49
|
end
|
50
50
|
|
51
51
|
def county
|
52
|
-
|
52
|
+
address_data['county']
|
53
53
|
end
|
54
54
|
|
55
55
|
def country
|
56
|
-
|
56
|
+
address_data['country']
|
57
57
|
end
|
58
58
|
|
59
59
|
def country_code
|
60
|
-
|
60
|
+
address_data['country_code']
|
61
61
|
end
|
62
62
|
|
63
63
|
def suburb
|
64
|
-
|
64
|
+
address_data['suburb']
|
65
65
|
end
|
66
66
|
|
67
67
|
def city_district
|
68
|
-
|
68
|
+
address_data['city_district']
|
69
69
|
end
|
70
70
|
|
71
71
|
def state_district
|
72
|
-
|
72
|
+
address_data['state_district']
|
73
73
|
end
|
74
74
|
|
75
75
|
def neighbourhood
|
76
|
-
|
76
|
+
address_data['neighbourhood']
|
77
77
|
end
|
78
78
|
|
79
79
|
def municipality
|
80
|
-
|
80
|
+
address_data['municipality']
|
81
81
|
end
|
82
82
|
|
83
83
|
def coordinates
|
84
|
+
return [] unless @data['lat'] && @data['lon']
|
85
|
+
|
84
86
|
[@data['lat'].to_f, @data['lon'].to_f]
|
85
87
|
end
|
86
88
|
|
@@ -109,5 +111,11 @@ module Geocoder::Result
|
|
109
111
|
end
|
110
112
|
end
|
111
113
|
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def address_data
|
118
|
+
@data['address'] || {}
|
119
|
+
end
|
112
120
|
end
|
113
121
|
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.7.
|
4
|
+
version: 1.7.4
|
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-03-14 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,
|
@@ -25,8 +25,7 @@ files:
|
|
25
25
|
- README.md
|
26
26
|
- bin/console
|
27
27
|
- bin/geocode
|
28
|
-
- examples/
|
29
|
-
- examples/autoexpire_cache_redis.rb
|
28
|
+
- examples/app_defined_lookup_services.rb
|
30
29
|
- examples/cache_bypass.rb
|
31
30
|
- examples/reverse_geocode_job.rb
|
32
31
|
- lib/easting_northing.rb
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# This class implements a cache with simple delegation to the the Dalli Memcached client
|
2
|
-
# https://github.com/mperham/dalli
|
3
|
-
#
|
4
|
-
# A TTL is set on initialization
|
5
|
-
|
6
|
-
class AutoexpireCacheDalli
|
7
|
-
def initialize(store, ttl = 86400)
|
8
|
-
@store = store
|
9
|
-
@keys = 'GeocoderDalliClientKeys'
|
10
|
-
@ttl = ttl
|
11
|
-
end
|
12
|
-
|
13
|
-
def [](url)
|
14
|
-
res = @store.get(url)
|
15
|
-
res = YAML::load(res) if res.present?
|
16
|
-
res
|
17
|
-
end
|
18
|
-
|
19
|
-
def []=(url, value)
|
20
|
-
if value.nil?
|
21
|
-
del(url)
|
22
|
-
else
|
23
|
-
key_cache_add(url) if @store.add(url, YAML::dump(value), @ttl)
|
24
|
-
end
|
25
|
-
value
|
26
|
-
end
|
27
|
-
|
28
|
-
def keys
|
29
|
-
key_cache
|
30
|
-
end
|
31
|
-
|
32
|
-
def del(url)
|
33
|
-
key_cache_delete(url) if @store.delete(url)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def key_cache
|
39
|
-
the_keys = @store.get(@keys)
|
40
|
-
if the_keys.nil?
|
41
|
-
@store.add(@keys, YAML::dump([]))
|
42
|
-
[]
|
43
|
-
else
|
44
|
-
YAML::load(the_keys)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def key_cache_add(key)
|
49
|
-
@store.replace(@keys, YAML::dump(key_cache << key))
|
50
|
-
end
|
51
|
-
|
52
|
-
def key_cache_delete(key)
|
53
|
-
tmp = key_cache
|
54
|
-
tmp.delete(key)
|
55
|
-
@store.replace(@keys, YAML::dump(tmp))
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Here Dalli is set up as on Heroku using the Memcachier gem.
|
60
|
-
# https://devcenter.heroku.com/articles/memcachier#ruby
|
61
|
-
# On other setups you might have to specify your Memcached server in Dalli::Client.new
|
62
|
-
Geocoder.configure(:cache => AutoexpireCacheDalli.new(Dalli::Client.new))
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# This class implements a cache with simple delegation to the Redis store, but
|
2
|
-
# when it creates a key/value pair, it also sends an EXPIRE command with a TTL.
|
3
|
-
# It should be fairly simple to do the same thing with Memcached.
|
4
|
-
# Alternatively, this class could inherit from Redis, which would make most
|
5
|
-
# of the below methods unnecessary.
|
6
|
-
class AutoexpireCacheRedis
|
7
|
-
def initialize(store, ttl = 86400)
|
8
|
-
@store = store
|
9
|
-
@ttl = ttl
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](url)
|
13
|
-
@store.get(url)
|
14
|
-
end
|
15
|
-
|
16
|
-
def []=(url, value)
|
17
|
-
@store.set(url, value)
|
18
|
-
@store.expire(url, @ttl)
|
19
|
-
end
|
20
|
-
|
21
|
-
def keys
|
22
|
-
@store.keys
|
23
|
-
end
|
24
|
-
|
25
|
-
def del(url)
|
26
|
-
@store.del(url)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
Geocoder.configure(:cache => AutoexpireCacheRedis.new(Redis.new))
|