geocoder 1.8.2 → 1.8.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 +11 -0
- data/README.md +31 -2
- data/lib/geocoder/lookup.rb +6 -3
- data/lib/geocoder/lookups/amazon_location_service.rb +7 -4
- data/lib/geocoder/lookups/azure.rb +56 -0
- data/lib/geocoder/lookups/bing.rb +1 -1
- data/lib/geocoder/lookups/google_places_search.rb +1 -2
- data/lib/geocoder/lookups/ip2location_io.rb +62 -0
- data/lib/geocoder/lookups/ip2location_lite.rb +40 -0
- data/lib/geocoder/lookups/mapbox.rb +3 -3
- data/lib/geocoder/lookups/pdok_nl.rb +43 -0
- data/lib/geocoder/lookups/photon.rb +1 -1
- data/lib/geocoder/query.rb +1 -1
- data/lib/geocoder/results/amazon_location_service.rb +6 -1
- data/lib/geocoder/results/azure.rb +65 -0
- data/lib/geocoder/results/ip2location_io.rb +21 -0
- data/lib/geocoder/results/ip2location_lite.rb +47 -0
- data/lib/geocoder/results/mapbox.rb +27 -9
- data/lib/geocoder/results/pdok_nl.rb +62 -0
- data/lib/geocoder/version.rb +1 -1
- data/lib/maxmind_database.rb +8 -8
- metadata +39 -5
- data/lib/geocoder/lookups/dstk.rb +0 -22
- data/lib/geocoder/results/dstk.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c38644e83a9bde6c719bd519bd59c41d481d9e49e667bcbcd728ddfeffac6f4d
|
4
|
+
data.tar.gz: 87df789703eb008121749def42594a4a8739cbc1b722dbdca4fb0f26562ff4b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 676238630577eb0e79b4fdc572b98a509c332d86a6a96b2076e785e965f0ebc27304d03acb4a5973fd73a7922bf11e19ee16e4a484eea301f636ed219a0d29ff
|
7
|
+
data.tar.gz: 16a80ebb922111745d81ffa48bd16f651934d6cbfe123fcb99ad252111ff9178ed76c999f278d7938488843f92b07de0b9f20bc2619363c2834b9aa99bf41569
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,17 @@ 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.4 (2024 Dec 4)
|
7
|
+
-------------------
|
8
|
+
* Add support for Azure lookup (thanks github.com/AhlOct).
|
9
|
+
* Several fixes for Mapbox and Bing lookups (thanks github.com/tmh-dev and github.com/iBlackShadow).
|
10
|
+
|
11
|
+
1.8.3 (2024 May 2)
|
12
|
+
-------------------
|
13
|
+
* Add support for IP2Location LITE lookup (thanks github.com/ip2location).
|
14
|
+
* Add support for PDOK NL lookup (thanks github.com/opensourceame).
|
15
|
+
* Remove support for Data Science Toolkit lookup (defunct).
|
16
|
+
|
6
17
|
1.8.2 (2023 Jul 4)
|
7
18
|
-------------------
|
8
19
|
* Add support for PC Miler lookup (thanks github.com/alexdean).
|
data/README.md
CHANGED
@@ -375,6 +375,9 @@ Geocoder::Lookup.all_services.each{|service| Geocoder::Lookup.get(service).cache
|
|
375
375
|
|
376
376
|
Do *not* include the prefix when passing a URL to be expired. Expiring `:all` will only expire keys with the configured prefix -- it will *not* expire every entry in your key/value store.
|
377
377
|
|
378
|
+
In addition to conventional cache stores like Redis, it's possible to keep your cache in the database using `ActiveRecord`. For example see [this gist](https://gist.github.com/shqear93/4b07153b4ca7e4e4a41da492679f6c0e).
|
379
|
+
|
380
|
+
|
378
381
|
_Before you implement caching in your app please be sure that doing so does not violate the Terms of Service for your geocoding service._
|
379
382
|
|
380
383
|
Not all services support caching, [check the service limitations in the API guide for more information](https://github.com/alexreisner/geocoder/blob/master/README_API_GUIDE.md).
|
@@ -734,8 +737,34 @@ you should check your Gemfile to make sure the Mongoid gem is listed _before_ Ge
|
|
734
737
|
|
735
738
|
A lot of debugging time can be saved by understanding how Geocoder works with ActiveRecord. When you use the `near` scope or the `nearbys` method of a geocoded object, Geocoder creates an ActiveModel::Relation object which adds some attributes (eg: distance, bearing) to the SELECT clause. It also adds a condition to the WHERE clause to check that distance is within the given radius. Because the SELECT clause is modified, anything else that modifies the SELECT clause may produce strange results, for example:
|
736
739
|
|
737
|
-
* using
|
738
|
-
*
|
740
|
+
* using [`select` method (selects one or more columns)](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-select)
|
741
|
+
* using the [`pluck` method (gets an array with selecting one or more columns)](https://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-pluck)
|
742
|
+
* The same problem will appear with [ActiveRecord's `ids` method](https://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-ids).
|
743
|
+
* specifying another model through [`includes` (selects columns from other tables)](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-includes)
|
744
|
+
* See also Known Issues [using-near-with-includes](#using-near-with-select) section.
|
745
|
+
|
746
|
+
If you get an error in the above cases, try the following:
|
747
|
+
|
748
|
+
```ruby
|
749
|
+
# Use the :select option with the near scope to get the columns you want.
|
750
|
+
# Instead of City.near(...).select(:id, :name), try:
|
751
|
+
City.near("Omaha, NE", 20, select: "id, name")
|
752
|
+
|
753
|
+
# Pass a :select option to the near scope to get the columns you want.
|
754
|
+
# Then, Ruby's built-in pluck method gets arrays you want.
|
755
|
+
# Instead of City.near(...).pluck(:id) or City.near(...).ids,, try:
|
756
|
+
City.near("Omaha, NE", 20, select: "id, name").to_a.pluck(:id, :name)
|
757
|
+
City.near("Omaha, NE", 20, select: "id").to_a.pluck(:id)
|
758
|
+
|
759
|
+
# Pass a :select option to the near scope to get the columns you want.
|
760
|
+
# Instead of City.near(...).includes(:venues), try:
|
761
|
+
City.near("Omaha, NE", 20, select: "cities.*, venues.*").joins(:venues)
|
762
|
+
|
763
|
+
# This preload call will normally trigger two queries regardless of the
|
764
|
+
# number of results; one query on hotels, and one query on administrators.
|
765
|
+
# Instead of Hotel.near(...).includes(:administrator), try:
|
766
|
+
Hotel.near("London, UK", 50).joins(:administrator).preload(:administrator)
|
767
|
+
```
|
739
768
|
|
740
769
|
### Geocoding is Slow
|
741
770
|
|
data/lib/geocoder/lookup.rb
CHANGED
@@ -23,7 +23,7 @@ module Geocoder
|
|
23
23
|
# For example, Amazon Location Service uses the AWS gem, not HTTP REST requests, to fetch data.
|
24
24
|
#
|
25
25
|
def all_services_with_http_requests
|
26
|
-
all_services_except_test - [:amazon_location_service]
|
26
|
+
all_services_except_test - [:amazon_location_service, :maxmind_local, :geoip2, :ip2location_lite]
|
27
27
|
end
|
28
28
|
|
29
29
|
##
|
@@ -32,7 +32,7 @@ module Geocoder
|
|
32
32
|
def street_services
|
33
33
|
@street_services ||= [
|
34
34
|
:location_iq,
|
35
|
-
:
|
35
|
+
:azure,
|
36
36
|
:esri,
|
37
37
|
:google,
|
38
38
|
:google_premier,
|
@@ -48,6 +48,7 @@ module Geocoder
|
|
48
48
|
:uk_ordnance_survey_names,
|
49
49
|
:opencagedata,
|
50
50
|
:pelias,
|
51
|
+
:pdok_nl,
|
51
52
|
:pickpoint,
|
52
53
|
:here,
|
53
54
|
:baidu,
|
@@ -94,7 +95,9 @@ module Geocoder
|
|
94
95
|
:ip2location,
|
95
96
|
:ipgeolocation,
|
96
97
|
:ipqualityscore,
|
97
|
-
:ipbase
|
98
|
+
:ipbase,
|
99
|
+
:ip2location_io,
|
100
|
+
:ip2location_lite
|
98
101
|
]
|
99
102
|
end
|
100
103
|
|
@@ -11,15 +11,18 @@ module Geocoder::Lookup
|
|
11
11
|
params.merge!(index_name: configuration[:index_name])
|
12
12
|
|
13
13
|
# Aws::ParamValidator raises ArgumentError on unexpected keys
|
14
|
-
params.delete(:lookup)
|
15
|
-
|
14
|
+
params.delete(:lookup)
|
15
|
+
|
16
|
+
# Inherit language from configuration
|
17
|
+
params.merge!(language: configuration[:language])
|
18
|
+
|
16
19
|
resp = if query.reverse_geocode?
|
17
20
|
client.search_place_index_for_position(params.merge(position: query.coordinates.reverse))
|
18
21
|
else
|
19
22
|
client.search_place_index_for_text(params.merge(text: query.text))
|
20
23
|
end
|
21
|
-
|
22
|
-
resp.results
|
24
|
+
|
25
|
+
resp.results
|
23
26
|
end
|
24
27
|
|
25
28
|
private
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/azure'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Azure < Base
|
6
|
+
def name
|
7
|
+
'Azure'
|
8
|
+
end
|
9
|
+
|
10
|
+
def required_api_key_parts
|
11
|
+
['api_key']
|
12
|
+
end
|
13
|
+
|
14
|
+
def supported_protocols
|
15
|
+
[:https]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def base_query_url(query)
|
21
|
+
host = 'atlas.microsoft.com/search/address'
|
22
|
+
|
23
|
+
if query.reverse_geocode?
|
24
|
+
"#{protocol}://#{host}/reverse/json?"
|
25
|
+
else
|
26
|
+
"#{protocol}://#{host}/json?"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def query_url_params(query)
|
31
|
+
params = {
|
32
|
+
'api-version' => 1.0,
|
33
|
+
'language' => query.options[:language] || 'en',
|
34
|
+
'limit' => configuration[:limit] || 10,
|
35
|
+
'query' => query.sanitized_text,
|
36
|
+
'subscription-key' => configuration.api_key
|
37
|
+
}
|
38
|
+
|
39
|
+
params.merge(super)
|
40
|
+
end
|
41
|
+
|
42
|
+
def results(query)
|
43
|
+
return [] unless (doc = fetch_data(query))
|
44
|
+
|
45
|
+
return doc if doc['error']
|
46
|
+
|
47
|
+
if doc['results']&.any?
|
48
|
+
doc['results']
|
49
|
+
elsif doc['addresses']&.any?
|
50
|
+
doc['addresses']
|
51
|
+
else
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -19,7 +19,7 @@ module Geocoder::Lookup
|
|
19
19
|
private # ---------------------------------------------------------------
|
20
20
|
|
21
21
|
def base_query_url(query)
|
22
|
-
text =
|
22
|
+
text = ERB::Util.url_encode(query.sanitized_text.strip)
|
23
23
|
url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations/"
|
24
24
|
if query.reverse_geocode?
|
25
25
|
url + "#{text}?"
|
@@ -49,12 +49,11 @@ module Geocoder
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def default_fields
|
52
|
-
legacy = %w[id reference]
|
53
52
|
basic = %w[business_status formatted_address geometry icon name
|
54
53
|
photos place_id plus_code types]
|
55
54
|
contact = %w[opening_hours]
|
56
55
|
atmosphere = %W[price_level rating user_ratings_total]
|
57
|
-
format_fields(
|
56
|
+
format_fields(basic, contact, atmosphere)
|
58
57
|
end
|
59
58
|
|
60
59
|
def format_fields(*fields)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ip2location_io'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Ip2locationIo < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"IP2LocationIOApi"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
['key']
|
13
|
+
end
|
14
|
+
|
15
|
+
def supported_protocols
|
16
|
+
[:http, :https]
|
17
|
+
end
|
18
|
+
|
19
|
+
private # ----------------------------------------------------------------
|
20
|
+
|
21
|
+
def base_query_url(query)
|
22
|
+
"#{protocol}://api.ip2location.io/?"
|
23
|
+
end
|
24
|
+
|
25
|
+
def query_url_params(query)
|
26
|
+
super.merge(
|
27
|
+
key: configuration.api_key,
|
28
|
+
ip: query.sanitized_text,
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def results(query)
|
33
|
+
# don't look up a loopback or private address, just return the stored result
|
34
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
35
|
+
return [] unless doc = fetch_data(query)
|
36
|
+
if doc["response"] == "INVALID ACCOUNT"
|
37
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
|
38
|
+
return []
|
39
|
+
else
|
40
|
+
return [doc]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def reserved_result(query)
|
45
|
+
{
|
46
|
+
"ip" => "-",
|
47
|
+
"country_code" => "-",
|
48
|
+
"country_name" => "-",
|
49
|
+
"region_name" => "-",
|
50
|
+
"city_name" => "-",
|
51
|
+
"latitude" => null,
|
52
|
+
"longitude" => null,
|
53
|
+
"zip_code" => "-",
|
54
|
+
"time_zone" => "-",
|
55
|
+
"asn" => "-",
|
56
|
+
"as" => "-",
|
57
|
+
"is_proxy" => false
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ip2location_lite'
|
3
|
+
|
4
|
+
module Geocoder
|
5
|
+
module Lookup
|
6
|
+
class Ip2locationLite < Base
|
7
|
+
attr_reader :gem_name
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
unless configuration[:file].nil?
|
11
|
+
begin
|
12
|
+
@gem_name = 'ip2location_ruby'
|
13
|
+
require @gem_name
|
14
|
+
rescue LoadError
|
15
|
+
raise "Could not load IP2Location DB dependency. To use the IP2LocationLite lookup you must add the #{@gem_name} gem to your Gemfile or have it installed in your system."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
'IP2LocationLite'
|
23
|
+
end
|
24
|
+
|
25
|
+
def required_api_key_parts
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def results(query)
|
32
|
+
return [] unless configuration[:file]
|
33
|
+
|
34
|
+
i2l = Ip2location.new.open(configuration[:file].to_s)
|
35
|
+
result = i2l.get_all(query.to_s)
|
36
|
+
result.nil? ? [] : [result]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -30,14 +30,14 @@ module Geocoder::Lookup
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def mapbox_search_term(query)
|
33
|
-
require '
|
33
|
+
require 'erb' unless defined?(ERB) && defined?(ERB::Util.url_encode)
|
34
34
|
if query.reverse_geocode?
|
35
35
|
lat,lon = query.coordinates
|
36
|
-
"#{
|
36
|
+
"#{ERB::Util.url_encode lon},#{ERB::Util.url_encode lat}"
|
37
37
|
else
|
38
38
|
# truncate at first semicolon so Mapbox doesn't go into batch mode
|
39
39
|
# (see Github issue #1299)
|
40
|
-
|
40
|
+
ERB::Util.url_encode query.text.to_s.split(';').first.to_s
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/pdok_nl"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class PdokNl < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
'pdok NL'
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_protocols
|
12
|
+
[:https]
|
13
|
+
end
|
14
|
+
|
15
|
+
private # ---------------------------------------------------------------
|
16
|
+
|
17
|
+
def cache_key(query)
|
18
|
+
base_query_url(query) + hash_to_query(query_url_params(query))
|
19
|
+
end
|
20
|
+
|
21
|
+
def base_query_url(query)
|
22
|
+
"#{protocol}://api.pdok.nl/bzk/locatieserver/search/v3_1/free?"
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid_response?(response)
|
26
|
+
json = parse_json(response.body)
|
27
|
+
super(response) if json
|
28
|
+
end
|
29
|
+
|
30
|
+
def results(query)
|
31
|
+
return [] unless doc = fetch_data(query)
|
32
|
+
return doc['response']['docs']
|
33
|
+
end
|
34
|
+
|
35
|
+
def query_url_params(query)
|
36
|
+
{
|
37
|
+
fl: '*',
|
38
|
+
q: query.text,
|
39
|
+
wt: 'json'
|
40
|
+
}.merge(super)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/geocoder/query.rb
CHANGED
@@ -3,7 +3,8 @@ require 'geocoder/results/base'
|
|
3
3
|
module Geocoder::Result
|
4
4
|
class AmazonLocationService < Base
|
5
5
|
def initialize(result)
|
6
|
-
@place = result
|
6
|
+
@place = result.place
|
7
|
+
super
|
7
8
|
end
|
8
9
|
|
9
10
|
def coordinates
|
@@ -53,5 +54,9 @@ module Geocoder::Result
|
|
53
54
|
def country_code
|
54
55
|
@place.country
|
55
56
|
end
|
57
|
+
|
58
|
+
def place_id
|
59
|
+
data.place_id if data.respond_to?(:place_id)
|
60
|
+
end
|
56
61
|
end
|
57
62
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Azure < Base
|
5
|
+
def address
|
6
|
+
@data['address']['freeformAddress']
|
7
|
+
end
|
8
|
+
|
9
|
+
def building_number
|
10
|
+
@data['address']['buildingNumber']
|
11
|
+
end
|
12
|
+
|
13
|
+
def city
|
14
|
+
@data['address']['municipality']
|
15
|
+
end
|
16
|
+
|
17
|
+
def coordinates
|
18
|
+
if @data['position'].is_a?(String) # reverse geocoding result
|
19
|
+
@data['position'].split(',').map(&:to_f)
|
20
|
+
elsif @data['position'].is_a?(Hash) # forward geocoding result
|
21
|
+
[@data['position']['lat'], @data['position']['lon']]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def country
|
26
|
+
@data['address']['country']
|
27
|
+
end
|
28
|
+
|
29
|
+
def country_code
|
30
|
+
@data['address']['countryCode']
|
31
|
+
end
|
32
|
+
|
33
|
+
def district
|
34
|
+
@data['address']['municipalitySubdivision']
|
35
|
+
end
|
36
|
+
|
37
|
+
def postal_code
|
38
|
+
@data['address']['postalCode']
|
39
|
+
end
|
40
|
+
|
41
|
+
def province
|
42
|
+
@data['address']['countrySubdivision']
|
43
|
+
end
|
44
|
+
|
45
|
+
def state
|
46
|
+
@data['address']['countrySubdivision']
|
47
|
+
end
|
48
|
+
|
49
|
+
def state_code
|
50
|
+
@data['address']['countrySubdivisionCode']
|
51
|
+
end
|
52
|
+
|
53
|
+
def street_name
|
54
|
+
@data['address']['streetName']
|
55
|
+
end
|
56
|
+
|
57
|
+
def street_number
|
58
|
+
@data['address']['streetNumber']
|
59
|
+
end
|
60
|
+
|
61
|
+
def viewport
|
62
|
+
@data['viewport'] || {}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Ip2locationIo < Base
|
5
|
+
|
6
|
+
def address(format = :full)
|
7
|
+
"#{city_name} #{zip_code}, #{country_name}".sub(/^[ ,]*/, '')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.response_attributes
|
11
|
+
%w[ip country_code country_name region_name city_name latitude longitude
|
12
|
+
zip_code time_zone asn as is_proxy]
|
13
|
+
end
|
14
|
+
|
15
|
+
response_attributes.each do |attr|
|
16
|
+
define_method attr do
|
17
|
+
@data[attr] || ""
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Ip2locationLite < Base
|
5
|
+
|
6
|
+
def coordinates
|
7
|
+
[@data[:latitude], @data[:longitude]]
|
8
|
+
end
|
9
|
+
|
10
|
+
def city
|
11
|
+
@data[:city]
|
12
|
+
end
|
13
|
+
|
14
|
+
def state
|
15
|
+
@data[:region]
|
16
|
+
end
|
17
|
+
|
18
|
+
def state_code
|
19
|
+
"" # Not available in Maxmind's database
|
20
|
+
end
|
21
|
+
|
22
|
+
def country
|
23
|
+
@data[:country_long]
|
24
|
+
end
|
25
|
+
|
26
|
+
def country_code
|
27
|
+
@data[:country_short]
|
28
|
+
end
|
29
|
+
|
30
|
+
def postal_code
|
31
|
+
@data[:zipcode]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.response_attributes
|
35
|
+
%w[country_short country_long region latitude longitude isp
|
36
|
+
domain netspeed areacode iddcode timezone zipcode weatherstationname
|
37
|
+
weatherstationcode mcc mnc mobilebrand elevation usagetype addresstype
|
38
|
+
category district asn as]
|
39
|
+
end
|
40
|
+
|
41
|
+
response_attributes.each do |a|
|
42
|
+
define_method a do
|
43
|
+
@data[a] || ""
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -16,43 +16,61 @@ module Geocoder::Result
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def city
|
19
|
-
context_part('place')
|
19
|
+
data_part('place') || context_part('place')
|
20
20
|
end
|
21
21
|
|
22
22
|
def state
|
23
|
-
context_part('region')
|
23
|
+
data_part('region') || context_part('region')
|
24
24
|
end
|
25
25
|
|
26
26
|
def state_code
|
27
|
-
|
27
|
+
if id_matches_name?(data['id'], 'region')
|
28
|
+
value = data['properties']['short_code']
|
29
|
+
else
|
30
|
+
value = context_part('region', 'short_code')
|
31
|
+
end
|
32
|
+
|
28
33
|
value.split('-').last unless value.nil?
|
29
34
|
end
|
30
35
|
|
31
36
|
def postal_code
|
32
|
-
context_part('postcode')
|
37
|
+
data_part('postcode') || context_part('postcode')
|
33
38
|
end
|
34
39
|
|
35
40
|
def country
|
36
|
-
context_part('country')
|
41
|
+
data_part('country') || context_part('country')
|
37
42
|
end
|
38
43
|
|
39
44
|
def country_code
|
40
|
-
|
45
|
+
if id_matches_name?(data['id'], 'country')
|
46
|
+
value = data['properties']['short_code']
|
47
|
+
else
|
48
|
+
value = context_part('country', 'short_code')
|
49
|
+
end
|
50
|
+
|
41
51
|
value.upcase unless value.nil?
|
42
52
|
end
|
43
53
|
|
44
54
|
def neighborhood
|
45
|
-
context_part('neighborhood')
|
55
|
+
data_part('neighborhood') || context_part('neighborhood')
|
46
56
|
end
|
47
57
|
|
48
58
|
def address
|
49
|
-
[place_name
|
59
|
+
data['place_name']
|
50
60
|
end
|
51
61
|
|
52
62
|
private
|
53
63
|
|
64
|
+
def id_matches_name?(id, name)
|
65
|
+
id =~ Regexp.new(name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def data_part(name)
|
69
|
+
data['text'] if id_matches_name?(data['id'], name)
|
70
|
+
end
|
71
|
+
|
54
72
|
def context_part(name, key = 'text')
|
55
|
-
(context.detect { |c| c['id']
|
73
|
+
(context.detect { |c| id_matches_name?(c['id'], name) } || {})[key]
|
56
74
|
end
|
57
75
|
|
58
76
|
def context
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class PdokNl < Base
|
5
|
+
|
6
|
+
def response_attributes
|
7
|
+
@data
|
8
|
+
end
|
9
|
+
|
10
|
+
def coordinates
|
11
|
+
@data['centroide_ll'][6..-2].split(' ').map(&:to_f).reverse
|
12
|
+
end
|
13
|
+
|
14
|
+
def formatted_address
|
15
|
+
@data['weergavenaam']
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :address, :formatted_address
|
19
|
+
|
20
|
+
def province
|
21
|
+
@data['provincienaam']
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :state, :province
|
25
|
+
|
26
|
+
def city
|
27
|
+
@data['woonplaatsnaam']
|
28
|
+
end
|
29
|
+
|
30
|
+
def district
|
31
|
+
@data['gemeentenaam']
|
32
|
+
end
|
33
|
+
|
34
|
+
def street
|
35
|
+
@data['straatnaam']
|
36
|
+
end
|
37
|
+
|
38
|
+
def street_number
|
39
|
+
@data['huis_nlt']
|
40
|
+
end
|
41
|
+
|
42
|
+
def address_components
|
43
|
+
@data
|
44
|
+
end
|
45
|
+
|
46
|
+
def state_code
|
47
|
+
@data['provinciecode']
|
48
|
+
end
|
49
|
+
|
50
|
+
def postal_code
|
51
|
+
@data['postcode']
|
52
|
+
end
|
53
|
+
|
54
|
+
def country
|
55
|
+
"Netherlands"
|
56
|
+
end
|
57
|
+
|
58
|
+
def country_code
|
59
|
+
"NL"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/geocoder/version.rb
CHANGED
data/lib/maxmind_database.rb
CHANGED
@@ -35,6 +35,14 @@ module Geocoder
|
|
35
35
|
p[s..-1]
|
36
36
|
end
|
37
37
|
|
38
|
+
def archive_edition(package)
|
39
|
+
{
|
40
|
+
geolite_country_csv: "GeoLite2-Country-CSV",
|
41
|
+
geolite_city_csv: "GeoLite2-City-CSV",
|
42
|
+
geolite_asn_csv: "GeoLite2-ASN-CSV"
|
43
|
+
}[package]
|
44
|
+
end
|
45
|
+
|
38
46
|
private # -------------------------------------------------------------
|
39
47
|
|
40
48
|
def table_columns(table_name)
|
@@ -94,14 +102,6 @@ module Geocoder
|
|
94
102
|
base_url + archive_url_path(package)
|
95
103
|
end
|
96
104
|
|
97
|
-
def archive_edition(package)
|
98
|
-
{
|
99
|
-
geolite_country_csv: "GeoLite2-Country-CSV",
|
100
|
-
geolite_city_csv: "GeoLite2-City-CSV",
|
101
|
-
geolite_asn_csv: "GeoLite2-ASN-CSV"
|
102
|
-
}[package]
|
103
|
-
end
|
104
|
-
|
105
105
|
def base_url(edition)
|
106
106
|
"https://download.maxmind.com/app/geoip_download?edition_id=#{edition}&license_key=#{ENV['LICENSE_KEY']}&suffix=zip"
|
107
107
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geocoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.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:
|
12
|
-
dependencies:
|
11
|
+
date: 2024-12-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base64
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: csv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
13
41
|
description: Object geocoding (by street or IP address), reverse geocoding (coordinates
|
14
42
|
to street address), distance queries for ActiveRecord and Mongoid, result caching,
|
15
43
|
and more. Designed for Rails but works with Sinatra and other Rack frameworks too.
|
@@ -54,13 +82,13 @@ files:
|
|
54
82
|
- lib/geocoder/lookups/abstract_api.rb
|
55
83
|
- lib/geocoder/lookups/amap.rb
|
56
84
|
- lib/geocoder/lookups/amazon_location_service.rb
|
85
|
+
- lib/geocoder/lookups/azure.rb
|
57
86
|
- lib/geocoder/lookups/baidu.rb
|
58
87
|
- lib/geocoder/lookups/baidu_ip.rb
|
59
88
|
- lib/geocoder/lookups/ban_data_gouv_fr.rb
|
60
89
|
- lib/geocoder/lookups/base.rb
|
61
90
|
- lib/geocoder/lookups/bing.rb
|
62
91
|
- lib/geocoder/lookups/db_ip_com.rb
|
63
|
-
- lib/geocoder/lookups/dstk.rb
|
64
92
|
- lib/geocoder/lookups/esri.rb
|
65
93
|
- lib/geocoder/lookups/freegeoip.rb
|
66
94
|
- lib/geocoder/lookups/geoapify.rb
|
@@ -74,6 +102,8 @@ files:
|
|
74
102
|
- lib/geocoder/lookups/google_premier.rb
|
75
103
|
- lib/geocoder/lookups/here.rb
|
76
104
|
- lib/geocoder/lookups/ip2location.rb
|
105
|
+
- lib/geocoder/lookups/ip2location_io.rb
|
106
|
+
- lib/geocoder/lookups/ip2location_lite.rb
|
77
107
|
- lib/geocoder/lookups/ipapi_com.rb
|
78
108
|
- lib/geocoder/lookups/ipbase.rb
|
79
109
|
- lib/geocoder/lookups/ipdata_co.rb
|
@@ -95,6 +125,7 @@ files:
|
|
95
125
|
- lib/geocoder/lookups/opencagedata.rb
|
96
126
|
- lib/geocoder/lookups/osmnames.rb
|
97
127
|
- lib/geocoder/lookups/pc_miler.rb
|
128
|
+
- lib/geocoder/lookups/pdok_nl.rb
|
98
129
|
- lib/geocoder/lookups/pelias.rb
|
99
130
|
- lib/geocoder/lookups/photon.rb
|
100
131
|
- lib/geocoder/lookups/pickpoint.rb
|
@@ -119,13 +150,13 @@ files:
|
|
119
150
|
- lib/geocoder/results/abstract_api.rb
|
120
151
|
- lib/geocoder/results/amap.rb
|
121
152
|
- lib/geocoder/results/amazon_location_service.rb
|
153
|
+
- lib/geocoder/results/azure.rb
|
122
154
|
- lib/geocoder/results/baidu.rb
|
123
155
|
- lib/geocoder/results/baidu_ip.rb
|
124
156
|
- lib/geocoder/results/ban_data_gouv_fr.rb
|
125
157
|
- lib/geocoder/results/base.rb
|
126
158
|
- lib/geocoder/results/bing.rb
|
127
159
|
- lib/geocoder/results/db_ip_com.rb
|
128
|
-
- lib/geocoder/results/dstk.rb
|
129
160
|
- lib/geocoder/results/esri.rb
|
130
161
|
- lib/geocoder/results/freegeoip.rb
|
131
162
|
- lib/geocoder/results/geoapify.rb
|
@@ -139,6 +170,8 @@ files:
|
|
139
170
|
- lib/geocoder/results/google_premier.rb
|
140
171
|
- lib/geocoder/results/here.rb
|
141
172
|
- lib/geocoder/results/ip2location.rb
|
173
|
+
- lib/geocoder/results/ip2location_io.rb
|
174
|
+
- lib/geocoder/results/ip2location_lite.rb
|
142
175
|
- lib/geocoder/results/ipapi_com.rb
|
143
176
|
- lib/geocoder/results/ipbase.rb
|
144
177
|
- lib/geocoder/results/ipdata_co.rb
|
@@ -160,6 +193,7 @@ files:
|
|
160
193
|
- lib/geocoder/results/opencagedata.rb
|
161
194
|
- lib/geocoder/results/osmnames.rb
|
162
195
|
- lib/geocoder/results/pc_miler.rb
|
196
|
+
- lib/geocoder/results/pdok_nl.rb
|
163
197
|
- lib/geocoder/results/pelias.rb
|
164
198
|
- lib/geocoder/results/photon.rb
|
165
199
|
- lib/geocoder/results/pickpoint.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# More information about the Data Science Toolkit can be found at:
|
2
|
-
# http://www.datasciencetoolkit.org/. The provided APIs mimic the
|
3
|
-
# Google geocoding api.
|
4
|
-
|
5
|
-
require 'geocoder/lookups/google'
|
6
|
-
require 'geocoder/results/dstk'
|
7
|
-
|
8
|
-
module Geocoder::Lookup
|
9
|
-
class Dstk < Google
|
10
|
-
|
11
|
-
def name
|
12
|
-
"Data Science Toolkit"
|
13
|
-
end
|
14
|
-
|
15
|
-
private # ----------------------------------------------------------------
|
16
|
-
|
17
|
-
def base_query_url(query)
|
18
|
-
host = configuration[:host] || "www.datasciencetoolkit.org"
|
19
|
-
"#{protocol}://#{host}/maps/api/geocode/json?"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|