ultra-fast-mod 0.0.1
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/geocoder-1.8.6/CHANGELOG.md +669 -0
- data/geocoder-1.8.6/LICENSE +20 -0
- data/geocoder-1.8.6/README.md +827 -0
- data/geocoder-1.8.6/bin/console +13 -0
- data/geocoder-1.8.6/bin/geocode +5 -0
- data/geocoder-1.8.6/examples/app_defined_lookup_services.rb +22 -0
- data/geocoder-1.8.6/examples/cache_bypass.rb +48 -0
- data/geocoder-1.8.6/examples/reverse_geocode_job.rb +40 -0
- data/geocoder-1.8.6/lib/easting_northing.rb +171 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/config_generator.rb +14 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/templates/initializer.rb +27 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/geocoder-1.8.6/lib/generators/geocoder/migration_version.rb +15 -0
- data/geocoder-1.8.6/lib/geocoder/cache.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/base.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/generic.rb +35 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/redis.rb +34 -0
- data/geocoder-1.8.6/lib/geocoder/calculations.rb +420 -0
- data/geocoder-1.8.6/lib/geocoder/cli.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/configuration.rb +151 -0
- data/geocoder-1.8.6/lib/geocoder/configuration_hash.rb +11 -0
- data/geocoder-1.8.6/lib/geocoder/esri_token.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/exceptions.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/ip_address.rb +36 -0
- data/geocoder-1.8.6/lib/geocoder/kernel_logger.rb +25 -0
- data/geocoder-1.8.6/lib/geocoder/logger.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/lookup.rb +155 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amap.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amazon_location_service.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/azure.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/base.rb +351 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/bing.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/esri.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/freegeoip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoapify.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocodio.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoip2.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_details.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_search.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_premier.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/here.rb +73 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_io.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_lite.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipbase.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io_lite.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipstack.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/latlon.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/location_iq.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapbox.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapquest.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind.rb +90 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_local.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nominatim.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/osmnames.rb +57 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pc_miler.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pdok_nl.rb +43 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pelias.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/photon.rb +89 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pointpin.rb +69 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/smarty_streets.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/telize.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/tencent.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/test.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/twogis.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/yandex.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/models/active_record.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/models/base.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_base.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_mapper.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongoid.rb +32 -0
- data/geocoder-1.8.6/lib/geocoder/query.rb +125 -0
- data/geocoder-1.8.6/lib/geocoder/railtie.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/request.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/results/abstract_api.rb +146 -0
- data/geocoder-1.8.6/lib/geocoder/results/amap.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/results/amazon_location_service.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/azure.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu_ip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/geocoder-1.8.6/lib/geocoder/results/base.rb +79 -0
- data/geocoder-1.8.6/lib/geocoder/results/bing.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/db_ip_com.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/esri.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/freegeoip.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoapify.rb +179 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocoder_ca.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocodio.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoip2.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/google.rb +150 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_details.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_search.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_premier.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/here.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location.rb +22 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_io.rb +21 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_lite.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipapi_com.rb +45 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipbase.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipdata_co.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io_lite.rb +16 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipregistry.rb +304 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipstack.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/latlon.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/location_iq.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapbox.rb +80 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapquest.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind.rb +130 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_local.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/results/melissa_street.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/nominatim.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/results/opencagedata.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/results/osmnames.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/results/pc_miler.rb +98 -0
- data/geocoder-1.8.6/lib/geocoder/results/pdok_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/pelias.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/photon.rb +119 -0
- data/geocoder-1.8.6/lib/geocoder/results/pickpoint.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/pointpin.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcodes_io.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/smarty_streets.rb +142 -0
- data/geocoder-1.8.6/lib/geocoder/results/telize.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/tencent.rb +72 -0
- data/geocoder-1.8.6/lib/geocoder/results/test.rb +33 -0
- data/geocoder-1.8.6/lib/geocoder/results/twogis.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/yandex.rb +292 -0
- data/geocoder-1.8.6/lib/geocoder/sql.rb +110 -0
- data/geocoder-1.8.6/lib/geocoder/stores/active_record.rb +329 -0
- data/geocoder-1.8.6/lib/geocoder/stores/base.rb +115 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_base.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_mapper.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongoid.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/util.rb +29 -0
- data/geocoder-1.8.6/lib/geocoder/version.rb +3 -0
- data/geocoder-1.8.6/lib/geocoder.rb +48 -0
- data/geocoder-1.8.6/lib/maxmind_database.rb +109 -0
- data/geocoder-1.8.6/lib/tasks/geocoder.rake +54 -0
- data/geocoder-1.8.6/lib/tasks/maxmind.rake +73 -0
- data/ultra-fast-mod.gemspec +12 -0
- metadata +214 -0
|
@@ -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,40 @@
|
|
|
1
|
+
require 'timeout'
|
|
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
|
+
class NetworkError < Error
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'resolv'
|
|
2
|
+
module Geocoder
|
|
3
|
+
class IpAddress < String
|
|
4
|
+
PRIVATE_IPS = [
|
|
5
|
+
'10.0.0.0/8',
|
|
6
|
+
'172.16.0.0/12',
|
|
7
|
+
'192.168.0.0/16',
|
|
8
|
+
].map { |ip| IPAddr.new(ip) }.freeze
|
|
9
|
+
|
|
10
|
+
def initialize(ip)
|
|
11
|
+
ip = ip.to_string if ip.is_a?(IPAddr)
|
|
12
|
+
if ip.is_a?(Hash)
|
|
13
|
+
super(**ip)
|
|
14
|
+
else
|
|
15
|
+
super(ip)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def internal?
|
|
20
|
+
loopback? || private?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def loopback?
|
|
24
|
+
valid? and !!(self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def private?
|
|
28
|
+
valid? && PRIVATE_IPS.any? { |ip| ip.include?(self) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def valid?
|
|
32
|
+
ip = self[/(?<=\[)(.*?)(?=\])/] || self
|
|
33
|
+
!!((ip =~ Resolv::IPv4::Regex) || (ip =~ Resolv::IPv6::Regex))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
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,155 @@
|
|
|
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
|
+
# Array of valid Lookup service names, excluding any that do not build their own HTTP requests.
|
|
23
|
+
# For example, Amazon Location Service uses the AWS gem, not HTTP REST requests, to fetch data.
|
|
24
|
+
#
|
|
25
|
+
def all_services_with_http_requests
|
|
26
|
+
all_services_except_test - [:amazon_location_service, :maxmind_local, :geoip2, :ip2location_lite]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# All street address lookup services, default first.
|
|
31
|
+
#
|
|
32
|
+
def street_services
|
|
33
|
+
@street_services ||= [
|
|
34
|
+
:location_iq,
|
|
35
|
+
:azure,
|
|
36
|
+
:esri,
|
|
37
|
+
:google,
|
|
38
|
+
:google_premier,
|
|
39
|
+
:google_places_details,
|
|
40
|
+
:google_places_search,
|
|
41
|
+
:bing,
|
|
42
|
+
:geocoder_ca,
|
|
43
|
+
:yandex,
|
|
44
|
+
:nationaal_georegister_nl,
|
|
45
|
+
:nominatim,
|
|
46
|
+
:mapbox,
|
|
47
|
+
:mapquest,
|
|
48
|
+
:uk_ordnance_survey_names,
|
|
49
|
+
:opencagedata,
|
|
50
|
+
:pelias,
|
|
51
|
+
:pdok_nl,
|
|
52
|
+
:pickpoint,
|
|
53
|
+
:here,
|
|
54
|
+
:baidu,
|
|
55
|
+
:tencent,
|
|
56
|
+
:geocodio,
|
|
57
|
+
:smarty_streets,
|
|
58
|
+
:postcode_anywhere_uk,
|
|
59
|
+
:postcodes_io,
|
|
60
|
+
:geoportail_lu,
|
|
61
|
+
:ban_data_gouv_fr,
|
|
62
|
+
:test,
|
|
63
|
+
:latlon,
|
|
64
|
+
:amap,
|
|
65
|
+
:osmnames,
|
|
66
|
+
:melissa_street,
|
|
67
|
+
:amazon_location_service,
|
|
68
|
+
:geoapify,
|
|
69
|
+
:photon,
|
|
70
|
+
:twogis,
|
|
71
|
+
:pc_miler
|
|
72
|
+
]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# All IP address lookup services, default first.
|
|
77
|
+
#
|
|
78
|
+
def ip_services
|
|
79
|
+
@ip_services ||= [
|
|
80
|
+
:baidu_ip,
|
|
81
|
+
:abstract_api,
|
|
82
|
+
:freegeoip,
|
|
83
|
+
:geoip2,
|
|
84
|
+
:maxmind,
|
|
85
|
+
:maxmind_local,
|
|
86
|
+
:telize,
|
|
87
|
+
:pointpin,
|
|
88
|
+
:maxmind_geoip2,
|
|
89
|
+
:ipinfo_io,
|
|
90
|
+
:ipinfo_io_lite,
|
|
91
|
+
:ipregistry,
|
|
92
|
+
:ipapi_com,
|
|
93
|
+
:ipdata_co,
|
|
94
|
+
:db_ip_com,
|
|
95
|
+
:ipstack,
|
|
96
|
+
:ip2location,
|
|
97
|
+
:ipgeolocation,
|
|
98
|
+
:ipqualityscore,
|
|
99
|
+
:ipbase,
|
|
100
|
+
:ip2location_io,
|
|
101
|
+
:ip2location_lite
|
|
102
|
+
]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
attr_writer :street_services, :ip_services
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# Retrieve a Lookup object from the store.
|
|
109
|
+
# Use this instead of Geocoder::Lookup::X.new to get an
|
|
110
|
+
# already-configured Lookup object.
|
|
111
|
+
#
|
|
112
|
+
def get(name)
|
|
113
|
+
@services = {} unless defined?(@services)
|
|
114
|
+
@services[name] = spawn(name) unless @services.include?(name)
|
|
115
|
+
@services[name]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
private # -----------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Spawn a Lookup of the given name.
|
|
123
|
+
#
|
|
124
|
+
def spawn(name)
|
|
125
|
+
if all_services.include?(name)
|
|
126
|
+
name = name.to_s
|
|
127
|
+
instantiate_lookup(name)
|
|
128
|
+
else
|
|
129
|
+
valids = all_services.map(&:inspect).join(", ")
|
|
130
|
+
raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
|
|
131
|
+
"(#{name.inspect} is not one of: #{valids})."
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Convert an "underscore" version of a name into a "class" version.
|
|
137
|
+
#
|
|
138
|
+
def classify_name(filename)
|
|
139
|
+
filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
##
|
|
143
|
+
# Safely instantiate Lookup
|
|
144
|
+
#
|
|
145
|
+
def instantiate_lookup(name)
|
|
146
|
+
class_name = classify_name(name)
|
|
147
|
+
begin
|
|
148
|
+
Geocoder::Lookup.const_get(class_name, inherit=false)
|
|
149
|
+
rescue NameError
|
|
150
|
+
require "geocoder/lookups/#{name}"
|
|
151
|
+
end
|
|
152
|
+
Geocoder::Lookup.const_get(class_name).new
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/abstract_api'
|
|
5
|
+
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class AbstractApi < Base
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Abstract API"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def required_api_key_parts
|
|
14
|
+
['api_key']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def supported_protocols
|
|
18
|
+
[:https]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private # ---------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def base_query_url(query)
|
|
24
|
+
"#{protocol}://ipgeolocation.abstractapi.com/v1/?"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def query_url_params(query)
|
|
28
|
+
params = {api_key: configuration.api_key}
|
|
29
|
+
|
|
30
|
+
ip_address = query.sanitized_text
|
|
31
|
+
if ip_address.is_a?(String) && ip_address.length > 0
|
|
32
|
+
params[:ip_address] = ip_address
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
params.merge(super)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def results(query, reverse = false)
|
|
39
|
+
if doc = fetch_data(query)
|
|
40
|
+
[doc]
|
|
41
|
+
else
|
|
42
|
+
[]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -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
|
+
Geocoder.log(:warn, "#{self.name} Geocoding API error: invalid api key.")
|
|
36
|
+
else
|
|
37
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
38
|
+
Geocoder.log(: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
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/amazon_location_service'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class AmazonLocationService < Base
|
|
6
|
+
def results(query)
|
|
7
|
+
params = query.options.dup
|
|
8
|
+
|
|
9
|
+
# index_name is required
|
|
10
|
+
# Aws::ParamValidator raises ArgumentError on missing required keys
|
|
11
|
+
params.merge!(index_name: configuration[:index_name])
|
|
12
|
+
|
|
13
|
+
# Aws::ParamValidator raises ArgumentError on unexpected keys
|
|
14
|
+
params.delete(:lookup)
|
|
15
|
+
|
|
16
|
+
# Inherit language from configuration
|
|
17
|
+
params.merge!(language: configuration[:language])
|
|
18
|
+
|
|
19
|
+
resp = if query.reverse_geocode?
|
|
20
|
+
client.search_place_index_for_position(params.merge(position: query.coordinates.reverse))
|
|
21
|
+
else
|
|
22
|
+
client.search_place_index_for_text(params.merge(text: query.text))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
resp.results
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def client
|
|
31
|
+
return @client if @client
|
|
32
|
+
require_sdk
|
|
33
|
+
keys = configuration.api_key
|
|
34
|
+
if keys
|
|
35
|
+
@client = Aws::LocationService::Client.new(**{
|
|
36
|
+
region: keys[:region],
|
|
37
|
+
access_key_id: keys[:access_key_id],
|
|
38
|
+
secret_access_key: keys[:secret_access_key]
|
|
39
|
+
}.compact)
|
|
40
|
+
else
|
|
41
|
+
@client = Aws::LocationService::Client.new
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def require_sdk
|
|
46
|
+
begin
|
|
47
|
+
require 'aws-sdk-locationservice'
|
|
48
|
+
rescue LoadError
|
|
49
|
+
raise_error(Geocoder::ConfigurationError) ||
|
|
50
|
+
Geocoder.log(
|
|
51
|
+
:error,
|
|
52
|
+
"Couldn't load the Amazon Location Service SDK. " +
|
|
53
|
+
"Install it with: gem install aws-sdk-locationservice -v '~> 1.4'"
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -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
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
# HTTP only
|
|
16
|
+
def supported_protocols
|
|
17
|
+
[:http]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private # ---------------------------------------------------------------
|
|
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
|
+
|
|
30
|
+
def results(query, reverse = false)
|
|
31
|
+
return [] unless doc = fetch_data(query)
|
|
32
|
+
case doc['status']
|
|
33
|
+
when 0
|
|
34
|
+
return [doc[content_key]] unless doc[content_key].blank?
|
|
35
|
+
when 1, 3, 4
|
|
36
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
37
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: server error.")
|
|
38
|
+
when 2
|
|
39
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
40
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid request.")
|
|
41
|
+
when 5
|
|
42
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
43
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
|
|
44
|
+
when 101, 102, 200..299
|
|
45
|
+
raise_error(Geocoder::RequestDenied, "request denied") ||
|
|
46
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: request denied.")
|
|
47
|
+
when 300..399
|
|
48
|
+
raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
|
|
49
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: over query limit.")
|
|
50
|
+
end
|
|
51
|
+
return []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def query_url_params(query)
|
|
55
|
+
{
|
|
56
|
+
(query.reverse_geocode? ? :location : :address) => query.sanitized_text,
|
|
57
|
+
:ak => configuration.api_key,
|
|
58
|
+
:output => "json"
|
|
59
|
+
}.merge(super)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'geocoder/lookups/baidu'
|
|
2
|
+
require 'geocoder/results/baidu_ip'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class BaiduIp < Baidu
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Baidu IP"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://api.map.baidu.com/location/ip?"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def content_key
|
|
18
|
+
'content'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def query_url_params(query)
|
|
22
|
+
{
|
|
23
|
+
:ip => query.sanitized_text,
|
|
24
|
+
:ak => configuration.api_key,
|
|
25
|
+
:coor => "bd09ll"
|
|
26
|
+
}.merge(super)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|