broken-geocoder 1.3.4
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 +7 -0
- data/CHANGELOG.md +467 -0
- data/LICENSE +20 -0
- data/README.md +1193 -0
- data/bin/geocode +5 -0
- data/examples/autoexpire_cache_dalli.rb +62 -0
- data/examples/autoexpire_cache_redis.rb +28 -0
- data/examples/cache_bypass.rb +48 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/generators/geocoder/config/config_generator.rb +14 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +21 -0
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +28 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +28 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/lib/geocoder.rb +48 -0
- data/lib/geocoder/cache.rb +90 -0
- data/lib/geocoder/calculations.rb +431 -0
- data/lib/geocoder/cli.rb +121 -0
- data/lib/geocoder/configuration.rb +129 -0
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +37 -0
- data/lib/geocoder/ip_address.rb +13 -0
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +110 -0
- data/lib/geocoder/lookups/baidu.rb +59 -0
- data/lib/geocoder/lookups/baidu_ip.rb +59 -0
- data/lib/geocoder/lookups/base.rb +325 -0
- data/lib/geocoder/lookups/bing.rb +80 -0
- data/lib/geocoder/lookups/dstk.rb +20 -0
- data/lib/geocoder/lookups/esri.rb +64 -0
- data/lib/geocoder/lookups/freegeoip.rb +51 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/lib/geocoder/lookups/geocoder_us.rb +43 -0
- data/lib/geocoder/lookups/geocodio.rb +42 -0
- data/lib/geocoder/lookups/geoip2.rb +45 -0
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +91 -0
- data/lib/geocoder/lookups/google_places_details.rb +50 -0
- data/lib/geocoder/lookups/google_premier.rb +47 -0
- data/lib/geocoder/lookups/here.rb +62 -0
- data/lib/geocoder/lookups/ipapi_com.rb +86 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +55 -0
- data/lib/geocoder/lookups/latlon.rb +59 -0
- data/lib/geocoder/lookups/mapbox.rb +53 -0
- data/lib/geocoder/lookups/mapquest.rb +59 -0
- data/lib/geocoder/lookups/mapzen.rb +15 -0
- data/lib/geocoder/lookups/maxmind.rb +90 -0
- data/lib/geocoder/lookups/maxmind_geoip2.rb +69 -0
- data/lib/geocoder/lookups/maxmind_local.rb +65 -0
- data/lib/geocoder/lookups/nominatim.rb +52 -0
- data/lib/geocoder/lookups/okf.rb +44 -0
- data/lib/geocoder/lookups/opencagedata.rb +58 -0
- data/lib/geocoder/lookups/ovi.rb +62 -0
- data/lib/geocoder/lookups/pelias.rb +64 -0
- data/lib/geocoder/lookups/pointpin.rb +68 -0
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +51 -0
- data/lib/geocoder/lookups/smarty_streets.rb +50 -0
- data/lib/geocoder/lookups/telize.rb +55 -0
- data/lib/geocoder/lookups/test.rb +44 -0
- data/lib/geocoder/lookups/yandex.rb +58 -0
- data/lib/geocoder/models/active_record.rb +50 -0
- data/lib/geocoder/models/base.rb +39 -0
- data/lib/geocoder/models/mongo_base.rb +62 -0
- data/lib/geocoder/models/mongo_mapper.rb +26 -0
- data/lib/geocoder/models/mongoid.rb +32 -0
- data/lib/geocoder/query.rb +111 -0
- data/lib/geocoder/railtie.rb +26 -0
- data/lib/geocoder/request.rb +83 -0
- data/lib/geocoder/results/baidu.rb +79 -0
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/base.rb +67 -0
- data/lib/geocoder/results/bing.rb +52 -0
- data/lib/geocoder/results/dstk.rb +6 -0
- data/lib/geocoder/results/esri.rb +75 -0
- data/lib/geocoder/results/freegeoip.rb +45 -0
- data/lib/geocoder/results/geocoder_ca.rb +60 -0
- data/lib/geocoder/results/geocoder_us.rb +39 -0
- data/lib/geocoder/results/geocodio.rb +70 -0
- data/lib/geocoder/results/geoip2.rb +62 -0
- data/lib/geocoder/results/geoportail_lu.rb +69 -0
- data/lib/geocoder/results/google.rb +139 -0
- data/lib/geocoder/results/google_places_details.rb +35 -0
- data/lib/geocoder/results/google_premier.rb +6 -0
- data/lib/geocoder/results/here.rb +71 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/mapbox.rb +47 -0
- data/lib/geocoder/results/mapquest.rb +48 -0
- data/lib/geocoder/results/mapzen.rb +5 -0
- data/lib/geocoder/results/maxmind.rb +135 -0
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +49 -0
- data/lib/geocoder/results/nominatim.rb +99 -0
- data/lib/geocoder/results/okf.rb +106 -0
- data/lib/geocoder/results/opencagedata.rb +90 -0
- data/lib/geocoder/results/ovi.rb +71 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/pointpin.rb +40 -0
- data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/lib/geocoder/results/smarty_streets.rb +106 -0
- data/lib/geocoder/results/telize.rb +45 -0
- data/lib/geocoder/results/test.rb +33 -0
- data/lib/geocoder/results/yandex.rb +92 -0
- data/lib/geocoder/sql.rb +107 -0
- data/lib/geocoder/stores/active_record.rb +305 -0
- data/lib/geocoder/stores/base.rb +116 -0
- data/lib/geocoder/stores/mongo_base.rb +58 -0
- data/lib/geocoder/stores/mongo_mapper.rb +13 -0
- data/lib/geocoder/stores/mongoid.rb +13 -0
- data/lib/geocoder/version.rb +3 -0
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/maxmind_database.rb +109 -0
- data/lib/tasks/geocoder.rake +38 -0
- data/lib/tasks/maxmind.rake +73 -0
- metadata +167 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'geocoder/configuration_hash'
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
# Configuration options should be set by passing a hash:
|
|
8
|
+
#
|
|
9
|
+
# Geocoder.configure(
|
|
10
|
+
# :timeout => 5,
|
|
11
|
+
# :lookup => :yandex,
|
|
12
|
+
# :api_key => "2a9fsa983jaslfj982fjasd",
|
|
13
|
+
# :units => :km
|
|
14
|
+
# )
|
|
15
|
+
#
|
|
16
|
+
def self.configure(options = nil, &block)
|
|
17
|
+
if !options.nil?
|
|
18
|
+
Configuration.instance.configure(options)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# Read-only access to the singleton's config data.
|
|
24
|
+
#
|
|
25
|
+
def self.config
|
|
26
|
+
Configuration.instance.data
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Read-only access to lookup-specific config data.
|
|
31
|
+
#
|
|
32
|
+
def self.config_for_lookup(lookup_name)
|
|
33
|
+
data = config.clone
|
|
34
|
+
data.reject!{ |key,value| !Configuration::OPTIONS.include?(key) }
|
|
35
|
+
if config.has_key?(lookup_name)
|
|
36
|
+
data.merge!(config[lookup_name])
|
|
37
|
+
end
|
|
38
|
+
data
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class Configuration
|
|
42
|
+
include Singleton
|
|
43
|
+
|
|
44
|
+
OPTIONS = [
|
|
45
|
+
:timeout,
|
|
46
|
+
:lookup,
|
|
47
|
+
:ip_lookup,
|
|
48
|
+
:language,
|
|
49
|
+
:http_headers,
|
|
50
|
+
:use_https,
|
|
51
|
+
:http_proxy,
|
|
52
|
+
:https_proxy,
|
|
53
|
+
:api_key,
|
|
54
|
+
:cache,
|
|
55
|
+
:cache_prefix,
|
|
56
|
+
:always_raise,
|
|
57
|
+
:units,
|
|
58
|
+
:distances,
|
|
59
|
+
:basic_auth,
|
|
60
|
+
:logger,
|
|
61
|
+
:kernel_logger_level
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
attr_accessor :data
|
|
65
|
+
|
|
66
|
+
def self.set_defaults
|
|
67
|
+
instance.set_defaults
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
OPTIONS.each do |o|
|
|
71
|
+
define_method o do
|
|
72
|
+
@data[o]
|
|
73
|
+
end
|
|
74
|
+
define_method "#{o}=" do |value|
|
|
75
|
+
@data[o] = value
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def configure(options)
|
|
80
|
+
@data.rmerge!(options)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def initialize # :nodoc
|
|
84
|
+
@data = Geocoder::ConfigurationHash.new
|
|
85
|
+
set_defaults
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def set_defaults
|
|
89
|
+
|
|
90
|
+
# geocoding options
|
|
91
|
+
@data[:timeout] = 3 # geocoding service timeout (secs)
|
|
92
|
+
@data[:lookup] = :google # name of street address geocoding service (symbol)
|
|
93
|
+
@data[:ip_lookup] = :freegeoip # name of IP address geocoding service (symbol)
|
|
94
|
+
@data[:language] = :en # ISO-639 language code
|
|
95
|
+
@data[:http_headers] = {} # HTTP headers for lookup
|
|
96
|
+
@data[:use_https] = false # use HTTPS for lookup requests? (if supported)
|
|
97
|
+
@data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
|
|
98
|
+
@data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
|
|
99
|
+
@data[:api_key] = nil # API key for geocoding service
|
|
100
|
+
@data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
|
|
101
|
+
@data[:cache_prefix] = "geocoder:" # prefix (string) to use for all cache keys
|
|
102
|
+
@data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
|
|
103
|
+
@data[:logger] = :kernel # :kernel or Logger instance
|
|
104
|
+
@data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
|
|
105
|
+
|
|
106
|
+
# exceptions that should not be rescued by default
|
|
107
|
+
# (if you want to implement custom error handling);
|
|
108
|
+
# supports SocketError and Timeout::Error
|
|
109
|
+
@data[:always_raise] = []
|
|
110
|
+
|
|
111
|
+
# calculation options
|
|
112
|
+
@data[:units] = :mi # :mi or :km
|
|
113
|
+
@data[:distances] = :linear # :linear or :spherical
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
instance_eval(OPTIONS.map do |option|
|
|
117
|
+
o = option.to_s
|
|
118
|
+
<<-EOS
|
|
119
|
+
def #{o}
|
|
120
|
+
instance.data[:#{o}]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def #{o}=(value)
|
|
124
|
+
instance.data[:#{o}] = value
|
|
125
|
+
end
|
|
126
|
+
EOS
|
|
127
|
+
end.join("\n\n"))
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class EsriToken
|
|
3
|
+
attr_accessor :value, :expires_at
|
|
4
|
+
|
|
5
|
+
def initialize(value, expires_at)
|
|
6
|
+
@value = value
|
|
7
|
+
@expires_at = expires_at
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_s
|
|
11
|
+
@value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def active?
|
|
15
|
+
@expires_at > Time.now
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.generate_token(client_id, client_secret, expires=1440)
|
|
19
|
+
# creates a new token that will expire in 1 day by default
|
|
20
|
+
getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
|
|
21
|
+
f: 'json',
|
|
22
|
+
client_id: client_id,
|
|
23
|
+
client_secret: client_secret,
|
|
24
|
+
grant_type: 'client_credentials',
|
|
25
|
+
expiration: expires # (minutes) max: 20160, default: 1 day
|
|
26
|
+
|
|
27
|
+
response = JSON.parse(getToken.body)
|
|
28
|
+
|
|
29
|
+
if response['error']
|
|
30
|
+
Geocoder.log(:warn, response['error'])
|
|
31
|
+
else
|
|
32
|
+
token_value = response['access_token']
|
|
33
|
+
expires_at = Time.now + (expires * 60)
|
|
34
|
+
new(token_value, expires_at)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'timeout' # required for Ruby 1.9.3
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ConfigurationError < Error
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class OverQueryLimitError < Error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ResponseParseError < Error
|
|
15
|
+
attr_reader :response
|
|
16
|
+
|
|
17
|
+
def initialize(response)
|
|
18
|
+
@response = response
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class RequestDenied < Error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class InvalidRequest < Error
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class InvalidApiKey < Error
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class ServiceUnavailable < Error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class LookupTimeout < ::Timeout::Error
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'resolv'
|
|
2
|
+
module Geocoder
|
|
3
|
+
class IpAddress < String
|
|
4
|
+
|
|
5
|
+
def loopback?
|
|
6
|
+
valid? and (self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def valid?
|
|
10
|
+
!!((self =~ Resolv::IPv4::Regex) || (self =~ Resolv::IPv6::Regex))
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class KernelLogger
|
|
3
|
+
include Singleton
|
|
4
|
+
|
|
5
|
+
def add(level, message)
|
|
6
|
+
return unless log_message_at_level?(level)
|
|
7
|
+
case level
|
|
8
|
+
when ::Logger::DEBUG, ::Logger::INFO
|
|
9
|
+
puts message
|
|
10
|
+
when ::Logger::WARN
|
|
11
|
+
warn message
|
|
12
|
+
when ::Logger::ERROR
|
|
13
|
+
raise message
|
|
14
|
+
when ::Logger::FATAL
|
|
15
|
+
fail message
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def log_message_at_level?(level)
|
|
22
|
+
level >= Geocoder.config.kernel_logger_level
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
|
|
5
|
+
def self.log(level, message)
|
|
6
|
+
Logger.instance.log(level, message)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Logger
|
|
10
|
+
include Singleton
|
|
11
|
+
|
|
12
|
+
SEVERITY = {
|
|
13
|
+
debug: ::Logger::DEBUG,
|
|
14
|
+
info: ::Logger::INFO,
|
|
15
|
+
warn: ::Logger::WARN,
|
|
16
|
+
error: ::Logger::ERROR,
|
|
17
|
+
fatal: ::Logger::FATAL
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def log(level, message)
|
|
21
|
+
unless valid_level?(level)
|
|
22
|
+
raise StandardError, "Geocoder tried to log a message with an invalid log level."
|
|
23
|
+
end
|
|
24
|
+
if current_logger.respond_to? :add
|
|
25
|
+
current_logger.add(SEVERITY[level], message)
|
|
26
|
+
else
|
|
27
|
+
raise Geocoder::ConfigurationError, "Please specify valid logger for Geocoder. " +
|
|
28
|
+
"Logger specified must be :kernel or must respond to `add(level, message)`."
|
|
29
|
+
end
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private # ----------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
def current_logger
|
|
36
|
+
logger = Geocoder.config[:logger]
|
|
37
|
+
if logger == :kernel
|
|
38
|
+
logger = Geocoder::KernelLogger.instance
|
|
39
|
+
end
|
|
40
|
+
logger
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def valid_level?(level)
|
|
44
|
+
SEVERITY.keys.include?(level)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "geocoder/lookups/test"
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
module Lookup
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Array of valid Lookup service names.
|
|
9
|
+
#
|
|
10
|
+
def all_services
|
|
11
|
+
street_services + ip_services
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Array of valid Lookup service names, excluding :test.
|
|
16
|
+
#
|
|
17
|
+
def all_services_except_test
|
|
18
|
+
all_services - [:test]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# All street address lookup services, default first.
|
|
23
|
+
#
|
|
24
|
+
def street_services
|
|
25
|
+
@street_services ||= [
|
|
26
|
+
:dstk,
|
|
27
|
+
:esri,
|
|
28
|
+
:google,
|
|
29
|
+
:google_premier,
|
|
30
|
+
:google_places_details,
|
|
31
|
+
:bing,
|
|
32
|
+
:geocoder_ca,
|
|
33
|
+
:geocoder_us,
|
|
34
|
+
:yandex,
|
|
35
|
+
:nominatim,
|
|
36
|
+
:mapbox,
|
|
37
|
+
:mapquest,
|
|
38
|
+
:mapzen,
|
|
39
|
+
:opencagedata,
|
|
40
|
+
:ovi,
|
|
41
|
+
:pelias,
|
|
42
|
+
:here,
|
|
43
|
+
:baidu,
|
|
44
|
+
:geocodio,
|
|
45
|
+
:smarty_streets,
|
|
46
|
+
:okf,
|
|
47
|
+
:postcode_anywhere_uk,
|
|
48
|
+
:geoportail_lu,
|
|
49
|
+
:test,
|
|
50
|
+
:latlon
|
|
51
|
+
]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# All IP address lookup services, default first.
|
|
56
|
+
#
|
|
57
|
+
def ip_services
|
|
58
|
+
@ip_services ||= [
|
|
59
|
+
:baidu_ip,
|
|
60
|
+
:freegeoip,
|
|
61
|
+
:geoip2,
|
|
62
|
+
:maxmind,
|
|
63
|
+
:maxmind_local,
|
|
64
|
+
:telize,
|
|
65
|
+
:pointpin,
|
|
66
|
+
:maxmind_geoip2,
|
|
67
|
+
:ipinfo_io,
|
|
68
|
+
:ipapi_com
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_writer :street_services, :ip_services
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# Retrieve a Lookup object from the store.
|
|
76
|
+
# Use this instead of Geocoder::Lookup::X.new to get an
|
|
77
|
+
# already-configured Lookup object.
|
|
78
|
+
#
|
|
79
|
+
def get(name)
|
|
80
|
+
@services = {} unless defined?(@services)
|
|
81
|
+
@services[name] = spawn(name) unless @services.include?(name)
|
|
82
|
+
@services[name]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
private # -----------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# Spawn a Lookup of the given name.
|
|
90
|
+
#
|
|
91
|
+
def spawn(name)
|
|
92
|
+
if all_services.include?(name)
|
|
93
|
+
name = name.to_s
|
|
94
|
+
require "geocoder/lookups/#{name}"
|
|
95
|
+
Geocoder::Lookup.const_get(classify_name(name)).new
|
|
96
|
+
else
|
|
97
|
+
valids = all_services.map(&:inspect).join(", ")
|
|
98
|
+
raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
|
|
99
|
+
"(#{name.inspect} is not one of: #{valids})."
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
##
|
|
104
|
+
# Convert an "underscore" version of a name into a "class" version.
|
|
105
|
+
#
|
|
106
|
+
def classify_name(filename)
|
|
107
|
+
filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/baidu"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Baidu < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Baidu"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def query_url(query)
|
|
16
|
+
"#{protocol}://api.map.baidu.com/geocoder/v2/?" + url_query_string(query)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# HTTP only
|
|
20
|
+
def supported_protocols
|
|
21
|
+
[:http]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private # ---------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
def results(query, reverse = false)
|
|
27
|
+
return [] unless doc = fetch_data(query)
|
|
28
|
+
case doc['status']
|
|
29
|
+
when 0
|
|
30
|
+
return [doc['result']] unless doc['result'].blank?
|
|
31
|
+
when 1, 3, 4
|
|
32
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
33
|
+
Geocoder.log(:warn, "Baidu Geocoding API error: server error.")
|
|
34
|
+
when 2
|
|
35
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
36
|
+
Geocoder.log(:warn, "Baidu Geocoding API error: invalid request.")
|
|
37
|
+
when 5
|
|
38
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
39
|
+
Geocoder.log(:warn, "Baidu Geocoding API error: invalid api key.")
|
|
40
|
+
when 101, 102, 200..299
|
|
41
|
+
raise_error(Geocoder::RequestDenied, "request denied") ||
|
|
42
|
+
Geocoder.log(:warn, "Baidu Geocoding API error: request denied.")
|
|
43
|
+
when 300..399
|
|
44
|
+
raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
|
|
45
|
+
Geocoder.log(:warn, "Baidu Geocoding API error: over query limit.")
|
|
46
|
+
end
|
|
47
|
+
return []
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def query_url_params(query)
|
|
51
|
+
{
|
|
52
|
+
(query.reverse_geocode? ? :location : :address) => query.sanitized_text,
|
|
53
|
+
:ak => configuration.api_key,
|
|
54
|
+
:output => "json"
|
|
55
|
+
}.merge(super)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|