geocoder 1.4.3 → 1.5.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 +43 -0
- data/README.md +364 -880
- data/examples/autoexpire_cache_redis.rb +3 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +3 -2
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +1 -1
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +1 -1
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +6 -2
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +2 -2
- data/lib/geocoder/exceptions.rb +1 -1
- data/lib/geocoder/ip_address.rb +1 -1
- data/lib/geocoder/lookup.rb +9 -4
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/baidu.rb +14 -10
- data/lib/geocoder/lookups/baidu_ip.rb +6 -35
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +4 -4
- data/lib/geocoder/lookups/base.rb +22 -4
- data/lib/geocoder/lookups/bing.rb +13 -12
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +1 -16
- data/lib/geocoder/lookups/freegeoip.rb +11 -2
- data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
- data/lib/geocoder/lookups/geocoder_us.rb +17 -9
- data/lib/geocoder/lookups/geocodio.rb +5 -5
- data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
- data/lib/geocoder/lookups/google.rb +13 -9
- data/lib/geocoder/lookups/google_places_details.rb +4 -4
- data/lib/geocoder/lookups/google_places_search.rb +4 -4
- data/lib/geocoder/lookups/google_premier.rb +11 -1
- data/lib/geocoder/lookups/here.rb +4 -4
- data/lib/geocoder/lookups/ip2location.rb +74 -0
- data/lib/geocoder/lookups/ipapi_com.rb +7 -12
- data/lib/geocoder/lookups/ipdata_co.rb +61 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +10 -19
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +4 -4
- data/lib/geocoder/lookups/location_iq.rb +26 -8
- data/lib/geocoder/lookups/mapbox.rb +12 -6
- data/lib/geocoder/lookups/mapquest.rb +4 -5
- data/lib/geocoder/lookups/maxmind.rb +4 -4
- data/lib/geocoder/lookups/maxmind_geoip2.rb +4 -0
- data/lib/geocoder/lookups/nominatim.rb +17 -5
- data/lib/geocoder/lookups/opencagedata.rb +7 -6
- data/lib/geocoder/lookups/pelias.rb +6 -6
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +7 -6
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +8 -8
- data/lib/geocoder/lookups/telize.rb +24 -4
- data/lib/geocoder/lookups/yandex.rb +10 -6
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/request.rb +32 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +10 -10
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +1 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/freegeoip.rb +0 -5
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geoip2.rb +24 -10
- data/lib/geocoder/results/geoportail_lu.rb +5 -3
- data/lib/geocoder/results/google.rb +16 -5
- data/lib/geocoder/results/here.rb +8 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_local.rb +0 -5
- data/lib/geocoder/results/nominatim.rb +12 -0
- data/lib/geocoder/results/opencagedata.rb +12 -2
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +7 -1
- data/lib/geocoder/results/telize.rb +0 -5
- data/lib/geocoder/results/test.rb +1 -1
- data/lib/geocoder/sql.rb +2 -2
- data/lib/geocoder/stores/active_record.rb +15 -4
- data/lib/geocoder/stores/base.rb +1 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/tasks/geocoder.rake +11 -3
- metadata +27 -10
- data/lib/geocoder/lookups/okf.rb +0 -44
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/results/okf.rb +0 -106
- data/lib/geocoder/results/ovi.rb +0 -71
|
@@ -8,11 +8,11 @@ class AutoexpireCacheRedis
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def [](url)
|
|
11
|
-
@store.
|
|
11
|
+
@store.get(url)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def []=(url, value)
|
|
15
|
-
@store.
|
|
15
|
+
@store.set(url, value)
|
|
16
16
|
@store.expire(url, @ttl)
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -25,4 +25,4 @@ class AutoexpireCacheRedis
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
Geocoder.configure(:cache => AutoexpireCacheRedis.new(Redis.new))
|
|
28
|
+
Geocoder.configure(:cache => AutoexpireCacheRedis.new(Redis.new))
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
Geocoder.configure(
|
|
2
2
|
# Geocoding options
|
|
3
3
|
# timeout: 3, # geocoding service timeout (secs)
|
|
4
|
-
# lookup: :
|
|
4
|
+
# lookup: :nominatim, # name of geocoding service (symbol)
|
|
5
|
+
# ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol)
|
|
5
6
|
# language: :en, # ISO-639 language code
|
|
6
7
|
# use_https: false, # use HTTPS for lookup requests? (if supported)
|
|
7
8
|
# http_proxy: nil, # HTTP proxy server (user:pass@host:port)
|
|
8
9
|
# https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
|
|
9
10
|
# api_key: nil, # API key for geocoding service
|
|
10
|
-
# cache: nil, # cache object (must respond to #[], #[]=, and #
|
|
11
|
+
# cache: nil, # cache object (must respond to #[], #[]=, and #del)
|
|
11
12
|
# cache_prefix: 'geocoder:', # prefix (string) to use for all cache keys
|
|
12
13
|
|
|
13
14
|
# Exceptions that should not be rescued by default
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
2
3
|
|
|
3
4
|
module Geocoder
|
|
4
5
|
module Generators
|
|
5
6
|
module Maxmind
|
|
6
7
|
class GeoliteCityGenerator < Rails::Generators::Base
|
|
7
8
|
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
8
10
|
|
|
9
11
|
source_root File.expand_path('../templates', __FILE__)
|
|
10
12
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
2
3
|
|
|
3
4
|
module Geocoder
|
|
4
5
|
module Generators
|
|
5
6
|
module Maxmind
|
|
6
7
|
class GeoliteCountryGenerator < Rails::Generators::Base
|
|
7
8
|
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
8
10
|
|
|
9
11
|
source_root File.expand_path('../templates', __FILE__)
|
|
10
12
|
|
data/lib/geocoder/cache.rb
CHANGED
|
@@ -40,7 +40,11 @@ module Geocoder
|
|
|
40
40
|
#
|
|
41
41
|
def expire(url)
|
|
42
42
|
if url == :all
|
|
43
|
-
|
|
43
|
+
if store.respond_to?(:keys)
|
|
44
|
+
urls.each{ |u| expire(u) }
|
|
45
|
+
else
|
|
46
|
+
raise(NoMethodError, "The Geocoder cache store must implement `#keys` for `expire(:all)` to work")
|
|
47
|
+
end
|
|
44
48
|
else
|
|
45
49
|
expire_single_url(url)
|
|
46
50
|
end
|
|
@@ -64,7 +68,7 @@ module Geocoder
|
|
|
64
68
|
# that have non-nil values.
|
|
65
69
|
#
|
|
66
70
|
def keys
|
|
67
|
-
store.keys.select{ |k| k.match(/^#{prefix}/) and
|
|
71
|
+
store.keys.select{ |k| k.match(/^#{prefix}/) and self[k] }
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
##
|
data/lib/geocoder/cli.rb
CHANGED
|
@@ -97,7 +97,7 @@ module Geocoder
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
if (result = Geocoder.search(query).first)
|
|
100
|
-
|
|
100
|
+
nominatim = Geocoder::Lookup.get(:nominatim)
|
|
101
101
|
lines = [
|
|
102
102
|
["Latitude", result.latitude],
|
|
103
103
|
["Longitude", result.longitude],
|
|
@@ -106,7 +106,7 @@ module Geocoder
|
|
|
106
106
|
["State/province", result.state],
|
|
107
107
|
["Postal code", result.postal_code],
|
|
108
108
|
["Country", result.country],
|
|
109
|
-
["
|
|
109
|
+
["Map", nominatim.map_link_url(result.coordinates)],
|
|
110
110
|
]
|
|
111
111
|
lines.each do |line|
|
|
112
112
|
out << (line[0] + ": ").ljust(18) + line[1].to_s + "\n"
|
|
@@ -97,8 +97,8 @@ module Geocoder
|
|
|
97
97
|
|
|
98
98
|
# geocoding options
|
|
99
99
|
@data[:timeout] = 3 # geocoding service timeout (secs)
|
|
100
|
-
@data[:lookup] = :
|
|
101
|
-
@data[:ip_lookup] = :
|
|
100
|
+
@data[:lookup] = :nominatim # name of street address geocoding service (symbol)
|
|
101
|
+
@data[:ip_lookup] = :ipinfo_io # name of IP address geocoding service (symbol)
|
|
102
102
|
@data[:language] = :en # ISO-639 language code
|
|
103
103
|
@data[:http_headers] = {} # HTTP headers for lookup
|
|
104
104
|
@data[:use_https] = false # use HTTPS for lookup requests? (if supported)
|
data/lib/geocoder/exceptions.rb
CHANGED
data/lib/geocoder/ip_address.rb
CHANGED
data/lib/geocoder/lookup.rb
CHANGED
|
@@ -39,18 +39,19 @@ module Geocoder
|
|
|
39
39
|
:mapquest,
|
|
40
40
|
:mapzen,
|
|
41
41
|
:opencagedata,
|
|
42
|
-
:ovi,
|
|
43
42
|
:pelias,
|
|
43
|
+
:pickpoint,
|
|
44
44
|
:here,
|
|
45
45
|
:baidu,
|
|
46
46
|
:geocodio,
|
|
47
47
|
:smarty_streets,
|
|
48
|
-
:okf,
|
|
49
48
|
:postcode_anywhere_uk,
|
|
49
|
+
:postcodes_io,
|
|
50
50
|
:geoportail_lu,
|
|
51
51
|
:ban_data_gouv_fr,
|
|
52
52
|
:test,
|
|
53
|
-
:latlon
|
|
53
|
+
:latlon,
|
|
54
|
+
:amap
|
|
54
55
|
]
|
|
55
56
|
end
|
|
56
57
|
|
|
@@ -68,7 +69,11 @@ module Geocoder
|
|
|
68
69
|
:pointpin,
|
|
69
70
|
:maxmind_geoip2,
|
|
70
71
|
:ipinfo_io,
|
|
71
|
-
:ipapi_com
|
|
72
|
+
:ipapi_com,
|
|
73
|
+
:ipdata_co,
|
|
74
|
+
:db_ip_com,
|
|
75
|
+
:ipstack,
|
|
76
|
+
:ip2location
|
|
72
77
|
]
|
|
73
78
|
end
|
|
74
79
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/amap"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Amap < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"AMap"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:http]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ---------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
path = query.reverse_geocode? ? 'regeo' : 'geo'
|
|
23
|
+
"http://restapi.amap.com/v3/geocode/#{path}?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def results(query, reverse = false)
|
|
27
|
+
return [] unless doc = fetch_data(query)
|
|
28
|
+
case [doc['status'], doc['info']]
|
|
29
|
+
when ['1', 'OK']
|
|
30
|
+
return doc['regeocodes'] unless doc['regeocodes'].blank?
|
|
31
|
+
return [doc['regeocode']] unless doc['regeocode'].blank?
|
|
32
|
+
return doc['geocodes'] unless doc['geocodes'].blank?
|
|
33
|
+
when ['0', 'INVALID_USER_KEY']
|
|
34
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
35
|
+
warn("#{self.name} Geocoding API error: invalid api key.")
|
|
36
|
+
else
|
|
37
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
38
|
+
warn("#{self.name} Geocoding API error: server error - [#{doc['info']}]")
|
|
39
|
+
end
|
|
40
|
+
return []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def query_url_params(query)
|
|
44
|
+
params = {
|
|
45
|
+
:key => configuration.api_key,
|
|
46
|
+
:output => "json"
|
|
47
|
+
}
|
|
48
|
+
if query.reverse_geocode?
|
|
49
|
+
params[:location] = revert_coordinates(query.text)
|
|
50
|
+
params[:extensions] = "all"
|
|
51
|
+
params[:coordsys] = "gps"
|
|
52
|
+
else
|
|
53
|
+
params[:address] = query.sanitized_text
|
|
54
|
+
end
|
|
55
|
+
params.merge(super)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def revert_coordinates(text)
|
|
59
|
+
[text[1],text[0]].join(",")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -12,10 +12,6 @@ module Geocoder::Lookup
|
|
|
12
12
|
["key"]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def query_url(query)
|
|
16
|
-
"#{protocol}://api.map.baidu.com/geocoder/v2/?" + url_query_string(query)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
15
|
# HTTP only
|
|
20
16
|
def supported_protocols
|
|
21
17
|
[:http]
|
|
@@ -23,26 +19,34 @@ module Geocoder::Lookup
|
|
|
23
19
|
|
|
24
20
|
private # ---------------------------------------------------------------
|
|
25
21
|
|
|
22
|
+
def base_query_url(query)
|
|
23
|
+
"#{protocol}://api.map.baidu.com/geocoder/v2/?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def content_key
|
|
27
|
+
'result'
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
def results(query, reverse = false)
|
|
27
31
|
return [] unless doc = fetch_data(query)
|
|
28
32
|
case doc['status']
|
|
29
33
|
when 0
|
|
30
|
-
return [doc[
|
|
34
|
+
return [doc[content_key]] unless doc[content_key].blank?
|
|
31
35
|
when 1, 3, 4
|
|
32
36
|
raise_error(Geocoder::Error, "server error.") ||
|
|
33
|
-
Geocoder.log(:warn, "
|
|
37
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: server error.")
|
|
34
38
|
when 2
|
|
35
39
|
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
36
|
-
Geocoder.log(:warn, "
|
|
40
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid request.")
|
|
37
41
|
when 5
|
|
38
42
|
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
39
|
-
Geocoder.log(:warn, "
|
|
43
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
|
|
40
44
|
when 101, 102, 200..299
|
|
41
45
|
raise_error(Geocoder::RequestDenied, "request denied") ||
|
|
42
|
-
Geocoder.log(:warn, "
|
|
46
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: request denied.")
|
|
43
47
|
when 300..399
|
|
44
48
|
raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
|
|
45
|
-
Geocoder.log(:warn, "
|
|
49
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: over query limit.")
|
|
46
50
|
end
|
|
47
51
|
return []
|
|
48
52
|
end
|
|
@@ -2,49 +2,20 @@ require 'geocoder/lookups/base'
|
|
|
2
2
|
require 'geocoder/results/baidu_ip'
|
|
3
3
|
|
|
4
4
|
module Geocoder::Lookup
|
|
5
|
-
class BaiduIp <
|
|
5
|
+
class BaiduIp < Baidu
|
|
6
6
|
|
|
7
7
|
def name
|
|
8
8
|
"Baidu IP"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
["key"]
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def query_url(query)
|
|
16
|
-
"#{protocol}://api.map.baidu.com/location/ip?" + url_query_string(query)
|
|
17
|
-
end
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
[:http]
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://api.map.baidu.com/location/ip?"
|
|
22
15
|
end
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def results(query, reverse = false)
|
|
27
|
-
return [] unless doc = fetch_data(query)
|
|
28
|
-
case doc['status']
|
|
29
|
-
when 0
|
|
30
|
-
return [doc['content']] unless doc['content'].blank?
|
|
31
|
-
when 1, 3, 4
|
|
32
|
-
raise_error(Geocoder::Error, "server error.") ||
|
|
33
|
-
Geocoder.log(:warn, "Baidu IP Geocoding API error: server error.")
|
|
34
|
-
when 2
|
|
35
|
-
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
36
|
-
Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid request.")
|
|
37
|
-
when 5
|
|
38
|
-
raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
|
|
39
|
-
Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid api key.")
|
|
40
|
-
when 101, 102, 200..299
|
|
41
|
-
raise_error(Geocoder::RequestDenied, "request denied.") ||
|
|
42
|
-
Geocoder.log(:warn, "Baidu IP Geocoding API error: request denied.")
|
|
43
|
-
when 300..399
|
|
44
|
-
raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
|
|
45
|
-
Geocoder.log(:warn, "Baidu IP Geocoding API error: over query limit.")
|
|
46
|
-
end
|
|
47
|
-
return []
|
|
17
|
+
def content_key
|
|
18
|
+
'content'
|
|
48
19
|
end
|
|
49
20
|
|
|
50
21
|
def query_url_params(query)
|
|
@@ -14,13 +14,13 @@ module Geocoder::Lookup
|
|
|
14
14
|
"https://www.openstreetmap.org/#map=19/#{coordinates.join('/')}"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
private # ---------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
def base_query_url(query)
|
|
18
20
|
method = query.reverse_geocode? ? "reverse" : "search"
|
|
19
|
-
"#{protocol}://api-adresse.data.gouv.fr/#{method}/?"
|
|
21
|
+
"#{protocol}://api-adresse.data.gouv.fr/#{method}/?"
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
private # ---------------------------------------------------------------
|
|
23
|
-
|
|
24
24
|
def any_result?(doc)
|
|
25
25
|
doc['features'].any?
|
|
26
26
|
end
|
|
@@ -4,7 +4,6 @@ require 'uri'
|
|
|
4
4
|
|
|
5
5
|
unless defined?(ActiveSupport::JSON)
|
|
6
6
|
begin
|
|
7
|
-
require 'rubygems' # for Ruby 1.8
|
|
8
7
|
require 'json'
|
|
9
8
|
rescue LoadError
|
|
10
9
|
raise LoadError, "Please install the 'json' or 'json_pure' gem to parse geocoder results."
|
|
@@ -72,8 +71,12 @@ module Geocoder
|
|
|
72
71
|
##
|
|
73
72
|
# URL to use for querying the geocoding engine.
|
|
74
73
|
#
|
|
74
|
+
# Subclasses should not modify this method. Instead they should define
|
|
75
|
+
# base_query_url and url_query_string. If absolutely necessary to
|
|
76
|
+
# subclss this method, they must also subclass #cache_key.
|
|
77
|
+
#
|
|
75
78
|
def query_url(query)
|
|
76
|
-
|
|
79
|
+
base_query_url(query) + url_query_string(query)
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
##
|
|
@@ -97,6 +100,14 @@ module Geocoder
|
|
|
97
100
|
|
|
98
101
|
private # -------------------------------------------------------------
|
|
99
102
|
|
|
103
|
+
##
|
|
104
|
+
# String which, when concatenated with url_query_string(query)
|
|
105
|
+
# produces the full query URL. Should include the "?" a the end.
|
|
106
|
+
#
|
|
107
|
+
def base_query_url(query)
|
|
108
|
+
fail
|
|
109
|
+
end
|
|
110
|
+
|
|
100
111
|
##
|
|
101
112
|
# An object with configuration data for this particular lookup.
|
|
102
113
|
#
|
|
@@ -147,7 +158,14 @@ module Geocoder
|
|
|
147
158
|
# something else (like the URL before OAuth encoding).
|
|
148
159
|
#
|
|
149
160
|
def cache_key(query)
|
|
150
|
-
|
|
161
|
+
base_query_url(query) + hash_to_query(cache_key_params(query))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def cache_key_params(query)
|
|
165
|
+
# omit api_key and token because they may vary among requests
|
|
166
|
+
query_url_params(query).reject do |key,value|
|
|
167
|
+
key.to_s.match /(key|token)/
|
|
168
|
+
end
|
|
151
169
|
end
|
|
152
170
|
|
|
153
171
|
##
|
|
@@ -286,7 +304,7 @@ module Geocoder
|
|
|
286
304
|
end
|
|
287
305
|
rescue Timeout::Error
|
|
288
306
|
raise Geocoder::LookupTimeout
|
|
289
|
-
rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ENETUNREACH
|
|
307
|
+
rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET
|
|
290
308
|
raise Geocoder::NetworkError
|
|
291
309
|
end
|
|
292
310
|
|
|
@@ -16,24 +16,20 @@ module Geocoder::Lookup
|
|
|
16
16
|
["key"]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def query_url(query)
|
|
20
|
-
base_url(query) + url_query_string(query)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
19
|
private # ---------------------------------------------------------------
|
|
24
20
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
text = CGI.escape(query.sanitized_text.strip)
|
|
23
|
+
url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations/"
|
|
24
|
+
if query.reverse_geocode?
|
|
25
|
+
url + "#{text}?"
|
|
26
|
+
else
|
|
29
27
|
if r = query.options[:region]
|
|
30
|
-
url << "
|
|
28
|
+
url << "#{r}/"
|
|
31
29
|
end
|
|
32
30
|
# use the more forgiving 'unstructured' query format to allow special
|
|
33
31
|
# chars, newlines, brackets, typos.
|
|
34
|
-
url + "?q
|
|
35
|
-
else
|
|
36
|
-
url + "/#{URI.escape(query.sanitized_text.strip)}?"
|
|
32
|
+
url + "?q=#{text}&"
|
|
37
33
|
end
|
|
38
34
|
end
|
|
39
35
|
|
|
@@ -44,6 +40,11 @@ module Geocoder::Lookup
|
|
|
44
40
|
return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : []
|
|
45
41
|
elsif doc['statusCode'] == 401 and doc["authenticationResultCode"] == "InvalidCredentials"
|
|
46
42
|
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid Bing API key.")
|
|
43
|
+
elsif doc['statusCode'] == 403
|
|
44
|
+
raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Bing Geocoding API error: Forbidden Request")
|
|
45
|
+
elsif [500, 503].include?(doc['statusCode'])
|
|
46
|
+
raise_error(Geocoder::ServiceUnavailable) ||
|
|
47
|
+
Geocoder.log(:warn, "Bing Geocoding API error: Service Unavailable")
|
|
47
48
|
else
|
|
48
49
|
Geocoder.log(:warn, "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']}).")
|
|
49
50
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/db_ip_com'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class DbIpCom < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
'DB-IP.com'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
[:https, :http]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def required_api_key_parts
|
|
16
|
+
['api_key']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://api.db-ip.com/v2/#{configuration.api_key}/#{query.sanitized_text}?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Same as query_url but without the api key.
|
|
27
|
+
#
|
|
28
|
+
def cache_key(query)
|
|
29
|
+
"#{protocol}://api.db-ip.com/v2/#{query.sanitized_text}?" + hash_to_query(cache_key_params(query))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def results(query)
|
|
33
|
+
return [] unless (doc = fetch_data(query))
|
|
34
|
+
|
|
35
|
+
case doc['error']
|
|
36
|
+
when 'maximum number of queries per day exceeded'
|
|
37
|
+
raise_error Geocoder::OverQueryLimitError ||
|
|
38
|
+
Geocoder.log(:warn, 'DB-API query limit exceeded.')
|
|
39
|
+
|
|
40
|
+
when 'invalid API key'
|
|
41
|
+
raise_error Geocoder::InvalidApiKey ||
|
|
42
|
+
Geocoder.log(:warn, 'Invalid DB-IP API key.')
|
|
43
|
+
when nil
|
|
44
|
+
[doc]
|
|
45
|
+
|
|
46
|
+
else
|
|
47
|
+
raise_error Geocoder::Error ||
|
|
48
|
+
Geocoder.log(:warn, "Request failed: #{doc['error']}")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -12,9 +12,11 @@ module Geocoder::Lookup
|
|
|
12
12
|
"Data Science Toolkit"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
private # ----------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
16
18
|
host = configuration[:host] || "www.datasciencetoolkit.org"
|
|
17
|
-
"#{protocol}://#{host}/maps/api/geocode/json?"
|
|
19
|
+
"#{protocol}://#{host}/maps/api/geocode/json?"
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -4,15 +4,11 @@ require 'geocoder/esri_token'
|
|
|
4
4
|
|
|
5
5
|
module Geocoder::Lookup
|
|
6
6
|
class Esri < Base
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
def name
|
|
9
9
|
"Esri"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def query_url(query)
|
|
13
|
-
base_query_url(query) + url_query_string(query)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
private # ---------------------------------------------------------------
|
|
17
13
|
|
|
18
14
|
def base_query_url(query)
|
|
@@ -34,17 +30,6 @@ module Geocoder::Lookup
|
|
|
34
30
|
end
|
|
35
31
|
end
|
|
36
32
|
|
|
37
|
-
def cache_key(query)
|
|
38
|
-
base_query_url(query) + hash_to_query(cache_key_params(query))
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def cache_key_params(query)
|
|
42
|
-
# omit api_key and token because they may vary among requests
|
|
43
|
-
query_url_params(query).reject do |key,value|
|
|
44
|
-
[:api_key, :token].include?(key)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
33
|
def query_url_params(query)
|
|
49
34
|
params = {
|
|
50
35
|
:f => "pjson",
|
|
@@ -9,7 +9,12 @@ module Geocoder::Lookup
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def supported_protocols
|
|
12
|
-
[:
|
|
12
|
+
if configuration[:host]
|
|
13
|
+
[:http, :https]
|
|
14
|
+
else
|
|
15
|
+
# use https for default host
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
13
18
|
end
|
|
14
19
|
|
|
15
20
|
def query_url(query)
|
|
@@ -18,6 +23,10 @@ module Geocoder::Lookup
|
|
|
18
23
|
|
|
19
24
|
private # ---------------------------------------------------------------
|
|
20
25
|
|
|
26
|
+
def cache_key(query)
|
|
27
|
+
query_url(query)
|
|
28
|
+
end
|
|
29
|
+
|
|
21
30
|
def parse_raw_data(raw_data)
|
|
22
31
|
raw_data.match(/^<html><title>404/) ? nil : super(raw_data)
|
|
23
32
|
end
|
|
@@ -45,7 +54,7 @@ module Geocoder::Lookup
|
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
def host
|
|
48
|
-
configuration[:host] || "freegeoip.
|
|
57
|
+
configuration[:host] || "freegeoip.net"
|
|
49
58
|
end
|
|
50
59
|
end
|
|
51
60
|
end
|
|
@@ -8,12 +8,12 @@ module Geocoder::Lookup
|
|
|
8
8
|
"Geocoder.ca"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def query_url(query)
|
|
12
|
-
"#{protocol}://geocoder.ca/?" + url_query_string(query)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
11
|
private # ---------------------------------------------------------------
|
|
16
12
|
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://geocoder.ca/?"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
17
|
def results(query)
|
|
18
18
|
return [] unless doc = fetch_data(query)
|
|
19
19
|
if doc['error'].nil?
|