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,114 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/esri"
|
|
3
|
+
require 'geocoder/esri_token'
|
|
4
|
+
|
|
5
|
+
module Geocoder::Lookup
|
|
6
|
+
class Esri < Base
|
|
7
|
+
|
|
8
|
+
def name
|
|
9
|
+
"Esri"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def supported_protocols
|
|
13
|
+
[:https]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private # ---------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
def base_query_url(query)
|
|
19
|
+
action = query.reverse_geocode? ? "reverseGeocode" : "find"
|
|
20
|
+
"#{protocol}://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/#{action}?"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def results(query)
|
|
24
|
+
return [] unless doc = fetch_data(query)
|
|
25
|
+
|
|
26
|
+
if (doc['error'].nil?)
|
|
27
|
+
if (!query.reverse_geocode?)
|
|
28
|
+
return [] if !doc['locations'] || doc['locations'].empty?
|
|
29
|
+
end
|
|
30
|
+
return [ doc ]
|
|
31
|
+
else
|
|
32
|
+
case [ doc['error']['code'] ]
|
|
33
|
+
when [498]
|
|
34
|
+
raise_error(Geocoder::InvalidApiKey, doc['error']['message']) ||
|
|
35
|
+
Geocoder.log(:warn, "#{self.name} Geocoding API error: #{doc['error']['message']}")
|
|
36
|
+
when [ 403 ]
|
|
37
|
+
raise_error(Geocoder::RequestDenied, 'ESRI request denied') ||
|
|
38
|
+
Geocoder.log(:warn, "#{self.name} ESRI request denied: #{doc['error']['message']}")
|
|
39
|
+
when [ 500 ], [501]
|
|
40
|
+
raise_error(Geocoder::ServiceUnavailable, 'ESRI service unavailable') ||
|
|
41
|
+
Geocoder.log(:warn, "#{self.name} ESRI service error: #{doc['error']['message']}")
|
|
42
|
+
else
|
|
43
|
+
raise_error(Geocoder::Error, doc['error']['message']) ||
|
|
44
|
+
Geocoder.log(:warn, "#{self.name} Geocoding error: #{doc['error']['message']}")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
return []
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def query_url_params(query)
|
|
51
|
+
params = {
|
|
52
|
+
:f => "pjson",
|
|
53
|
+
:outFields => "*"
|
|
54
|
+
}
|
|
55
|
+
if query.reverse_geocode?
|
|
56
|
+
params[:location] = query.coordinates.reverse.join(',')
|
|
57
|
+
else
|
|
58
|
+
params[:text] = query.sanitized_text
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
params[:token] = token(query)
|
|
62
|
+
|
|
63
|
+
if for_storage_value = for_storage(query)
|
|
64
|
+
params[:forStorage] = for_storage_value
|
|
65
|
+
end
|
|
66
|
+
params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
|
|
67
|
+
params[:preferredLabelValues] = configuration[:preferred_label_values] if configuration[:preferred_label_values]
|
|
68
|
+
|
|
69
|
+
params.merge(super)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def for_storage(query)
|
|
73
|
+
if query.options.has_key?(:for_storage)
|
|
74
|
+
query.options[:for_storage]
|
|
75
|
+
else
|
|
76
|
+
configuration[:for_storage]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def token(query)
|
|
81
|
+
token_instance = if query.options[:token]
|
|
82
|
+
query.options[:token]
|
|
83
|
+
else
|
|
84
|
+
configuration[:token]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if !valid_token_configured?(token_instance) && configuration.api_key
|
|
88
|
+
token_instance = create_and_save_token!(query)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
token_instance.to_s unless token_instance.nil?
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def valid_token_configured?(token_instance)
|
|
95
|
+
!token_instance.nil? && token_instance.active?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def create_and_save_token!(query)
|
|
99
|
+
token_instance = create_token
|
|
100
|
+
|
|
101
|
+
if query.options[:token]
|
|
102
|
+
query.options[:token] = token_instance
|
|
103
|
+
else
|
|
104
|
+
Geocoder.merge_into_lookup_config(:esri, token: token_instance)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
token_instance
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def create_token
|
|
111
|
+
Geocoder::EsriToken.generate_token(*configuration.api_key)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/freegeoip'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Freegeoip < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"FreeGeoIP"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
if configuration[:host]
|
|
13
|
+
[:https]
|
|
14
|
+
else
|
|
15
|
+
# use https for default host
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private # ---------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
def base_query_url(query)
|
|
23
|
+
"#{protocol}://#{host}/json/#{query.sanitized_text}?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def query_url_params(query)
|
|
27
|
+
{
|
|
28
|
+
:apikey => configuration.api_key
|
|
29
|
+
}.merge(super)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def parse_raw_data(raw_data)
|
|
33
|
+
raw_data.match(/^<html><title>404/) ? nil : super(raw_data)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def results(query)
|
|
37
|
+
# don't look up a loopback or private address, just return the stored result
|
|
38
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
|
39
|
+
# note: Freegeoip.net returns plain text "Not Found" on bad request
|
|
40
|
+
(doc = fetch_data(query)) ? [doc] : []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def reserved_result(ip)
|
|
44
|
+
{
|
|
45
|
+
"ip" => ip,
|
|
46
|
+
"city" => "",
|
|
47
|
+
"region_code" => "",
|
|
48
|
+
"region_name" => "",
|
|
49
|
+
"metro_code" => "",
|
|
50
|
+
"zip_code" => "",
|
|
51
|
+
"latitude" => "0",
|
|
52
|
+
"longitude" => "0",
|
|
53
|
+
"country_name" => "Reserved",
|
|
54
|
+
"country_code" => "RD"
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def host
|
|
59
|
+
configuration[:host] || "freegeoip.app"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/geoapify'
|
|
5
|
+
|
|
6
|
+
module Geocoder
|
|
7
|
+
module Lookup
|
|
8
|
+
# https://apidocs.geoapify.com/docs/geocoding/api
|
|
9
|
+
class Geoapify < Base
|
|
10
|
+
def name
|
|
11
|
+
'Geoapify'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def required_api_key_parts
|
|
15
|
+
['api_key']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def supported_protocols
|
|
19
|
+
[:https]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def base_query_url(query)
|
|
25
|
+
method = if query.reverse_geocode?
|
|
26
|
+
'reverse'
|
|
27
|
+
elsif query.options[:autocomplete]
|
|
28
|
+
'autocomplete'
|
|
29
|
+
else
|
|
30
|
+
'search'
|
|
31
|
+
end
|
|
32
|
+
"https://api.geoapify.com/v1/geocode/#{method}?"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def results(query)
|
|
36
|
+
return [] unless (doc = fetch_data(query))
|
|
37
|
+
|
|
38
|
+
# The rest of the status codes should be already handled by the default
|
|
39
|
+
# functionality as the API returns correct HTTP response codes in most
|
|
40
|
+
# cases. There may be some unhandled cases still (such as over query
|
|
41
|
+
# limit reached) but there is not enough documentation to cover them.
|
|
42
|
+
case doc['statusCode']
|
|
43
|
+
when 500
|
|
44
|
+
raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, doc['message'])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
return [] unless doc['type'] == 'FeatureCollection'
|
|
48
|
+
return [] unless doc['features'] || doc['features'].present?
|
|
49
|
+
|
|
50
|
+
doc['features']
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def query_url_params(query)
|
|
54
|
+
lang = query.language || configuration.language
|
|
55
|
+
params = { apiKey: configuration.api_key, lang: lang, limit: query.options[:limit] }
|
|
56
|
+
|
|
57
|
+
if query.reverse_geocode?
|
|
58
|
+
params.merge!(query_url_params_reverse(query))
|
|
59
|
+
else
|
|
60
|
+
params.merge!(query_url_params_coordinates(query))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
params.merge!(super)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def query_url_params_coordinates(query)
|
|
67
|
+
{ text: query.sanitized_text }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def query_url_params_reverse(query)
|
|
71
|
+
{
|
|
72
|
+
lat: query.coordinates[0],
|
|
73
|
+
lon: query.coordinates[1]
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/geocoder_ca"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class GeocoderCa < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Geocoder.ca"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://geocoder.ca/?"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def results(query)
|
|
18
|
+
return [] unless doc = fetch_data(query)
|
|
19
|
+
if doc['error'].nil?
|
|
20
|
+
return [doc]
|
|
21
|
+
elsif doc['error']['code'] == "005"
|
|
22
|
+
# "Postal Code is not in the proper Format" => no results, just shut up
|
|
23
|
+
else
|
|
24
|
+
Geocoder.log(:warn, "Geocoder.ca service error: #{doc['error']['code']} (#{doc['error']['description']}).")
|
|
25
|
+
end
|
|
26
|
+
return []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def query_url_params(query)
|
|
30
|
+
params = {
|
|
31
|
+
:geoit => "xml",
|
|
32
|
+
:jsonp => 1,
|
|
33
|
+
:callback => "test",
|
|
34
|
+
:auth => configuration.api_key
|
|
35
|
+
}.merge(super)
|
|
36
|
+
if query.reverse_geocode?
|
|
37
|
+
lat,lon = query.coordinates
|
|
38
|
+
params[:latt] = lat
|
|
39
|
+
params[:longt] = lon
|
|
40
|
+
params[:corner] = 1
|
|
41
|
+
params[:reverse] = 1
|
|
42
|
+
else
|
|
43
|
+
params[:locate] = query.sanitized_text
|
|
44
|
+
params[:showpostal] = 1
|
|
45
|
+
end
|
|
46
|
+
params
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def parse_raw_data(raw_data)
|
|
50
|
+
super raw_data[/^test\((.*)\)\;\s*$/, 1]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/geocodio"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Geocodio < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Geocodio"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def results(query)
|
|
12
|
+
return [] unless doc = fetch_data(query)
|
|
13
|
+
return doc["results"] if doc['error'].nil?
|
|
14
|
+
|
|
15
|
+
if doc['error'] == 'Invalid API key'
|
|
16
|
+
raise_error(Geocoder::InvalidApiKey) ||
|
|
17
|
+
Geocoder.log(:warn, "Geocodio service error: invalid API key.")
|
|
18
|
+
elsif doc['error'].match(/You have reached your daily maximum/)
|
|
19
|
+
raise_error(Geocoder::OverQueryLimitError, doc['error']) ||
|
|
20
|
+
Geocoder.log(:warn, "Geocodio service error: #{doc['error']}.")
|
|
21
|
+
else
|
|
22
|
+
raise_error(Geocoder::InvalidRequest, doc['error']) ||
|
|
23
|
+
Geocoder.log(:warn, "Geocodio service error: #{doc['error']}.")
|
|
24
|
+
end
|
|
25
|
+
[]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private # ---------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
def base_query_url(query)
|
|
31
|
+
path = query.reverse_geocode? ? "reverse" : "geocode"
|
|
32
|
+
"#{protocol}://api.geocod.io/v1.6/#{path}?"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def query_url_params(query)
|
|
36
|
+
{
|
|
37
|
+
:api_key => configuration.api_key,
|
|
38
|
+
:q => query.sanitized_text
|
|
39
|
+
}.merge(super)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/geoip2'
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Lookup
|
|
6
|
+
class Geoip2 < Base
|
|
7
|
+
attr_reader :gem_name
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
unless configuration[:file].nil?
|
|
11
|
+
begin
|
|
12
|
+
@gem_name = configuration[:lib] || 'maxminddb'
|
|
13
|
+
require @gem_name
|
|
14
|
+
rescue LoadError
|
|
15
|
+
raise "Could not load Maxmind DB dependency. To use the GeoIP2 lookup you must add the #{@gem_name} gem to your Gemfile or have it installed in your system."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@mmdb = db_class.new(configuration[:file].to_s)
|
|
19
|
+
end
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def name
|
|
24
|
+
'GeoIP2'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def required_api_key_parts
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def db_class
|
|
34
|
+
gem_name == 'hive_geoip2' ? Hive::GeoIP2 : MaxMindDB
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def results(query)
|
|
38
|
+
return [] unless configuration[:file]
|
|
39
|
+
|
|
40
|
+
if @mmdb.respond_to?(:local_ip_alias) && !configuration[:local_ip_alias].nil?
|
|
41
|
+
@mmdb.local_ip_alias = configuration[:local_ip_alias]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
result = @mmdb.lookup(query.to_s)
|
|
45
|
+
result.nil? ? [] : [result]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/geoportail_lu"
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Lookup
|
|
6
|
+
class GeoportailLu < Base
|
|
7
|
+
|
|
8
|
+
def name
|
|
9
|
+
"Geoportail.lu"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private # ---------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
def base_query_url(query)
|
|
15
|
+
if query.reverse_geocode?
|
|
16
|
+
reverse_geocode_url_base_path
|
|
17
|
+
else
|
|
18
|
+
search_url_base_path
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def search_url_base_path
|
|
23
|
+
"#{protocol}://api.geoportail.lu/geocoder/search?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def reverse_geocode_url_base_path
|
|
27
|
+
"#{protocol}://api.geoportail.lu/geocoder/reverseGeocode?"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def query_url_geoportail_lu_params(query)
|
|
31
|
+
query.reverse_geocode? ? reverse_geocode_params(query) : search_params(query)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def search_params(query)
|
|
35
|
+
{
|
|
36
|
+
queryString: query.sanitized_text
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reverse_geocode_params(query)
|
|
41
|
+
lat_lon = query.coordinates
|
|
42
|
+
{
|
|
43
|
+
lat: lat_lon.first,
|
|
44
|
+
lon: lat_lon.last
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def query_url_params(query)
|
|
49
|
+
query_url_geoportail_lu_params(query).merge(super)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def results(query)
|
|
53
|
+
return [] unless doc = fetch_data(query)
|
|
54
|
+
if doc['success'] == true
|
|
55
|
+
result = doc['results']
|
|
56
|
+
else
|
|
57
|
+
result = []
|
|
58
|
+
raise_error(Geocoder::Error) ||
|
|
59
|
+
Geocoder.log(:warn, "Geportail.lu Geocoding API error")
|
|
60
|
+
end
|
|
61
|
+
result
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/google"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Google < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Google"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def map_link_url(coordinates)
|
|
12
|
+
"http://maps.google.com/maps?q=#{coordinates.join(',')}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
# Google requires HTTPS if an API key is used.
|
|
17
|
+
if configuration.api_key
|
|
18
|
+
[:https]
|
|
19
|
+
else
|
|
20
|
+
[:http, :https]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private # ---------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
def base_query_url(query)
|
|
27
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def configure_ssl!(client)
|
|
31
|
+
client.instance_eval {
|
|
32
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
|
33
|
+
options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
|
|
34
|
+
if OpenSSL::SSL.const_defined?('OP_NO_COMPRESSION')
|
|
35
|
+
options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
|
36
|
+
end
|
|
37
|
+
@ssl_context.set_params({options: options})
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def valid_response?(response)
|
|
42
|
+
json = parse_json(response.body)
|
|
43
|
+
status = json["status"] if json
|
|
44
|
+
super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def result_root_attr
|
|
48
|
+
'results'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def results(query)
|
|
52
|
+
return [] unless doc = fetch_data(query)
|
|
53
|
+
case doc['status']
|
|
54
|
+
when "OK" # OK status implies >0 results
|
|
55
|
+
return doc[result_root_attr]
|
|
56
|
+
when "OVER_QUERY_LIMIT"
|
|
57
|
+
raise_error(Geocoder::OverQueryLimitError) ||
|
|
58
|
+
Geocoder.log(:warn, "#{name} API error: over query limit.")
|
|
59
|
+
when "REQUEST_DENIED"
|
|
60
|
+
raise_error(Geocoder::RequestDenied, doc['error_message']) ||
|
|
61
|
+
Geocoder.log(:warn, "#{name} API error: request denied (#{doc['error_message']}).")
|
|
62
|
+
when "INVALID_REQUEST"
|
|
63
|
+
raise_error(Geocoder::InvalidRequest, doc['error_message']) ||
|
|
64
|
+
Geocoder.log(:warn, "#{name} API error: invalid request (#{doc['error_message']}).")
|
|
65
|
+
end
|
|
66
|
+
return []
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def query_url_google_params(query)
|
|
70
|
+
params = {
|
|
71
|
+
:sensor => "false",
|
|
72
|
+
:language => (query.language || configuration.language)
|
|
73
|
+
}
|
|
74
|
+
if query.options[:google_place_id]
|
|
75
|
+
params[:place_id] = query.sanitized_text
|
|
76
|
+
else
|
|
77
|
+
params[(query.reverse_geocode? ? :latlng : :address)] = query.sanitized_text
|
|
78
|
+
end
|
|
79
|
+
unless (bounds = query.options[:bounds]).nil?
|
|
80
|
+
params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join('|')
|
|
81
|
+
end
|
|
82
|
+
unless (region = query.options[:region]).nil?
|
|
83
|
+
params[:region] = region
|
|
84
|
+
end
|
|
85
|
+
unless (components = query.options[:components]).nil?
|
|
86
|
+
params[:components] = components.is_a?(Array) ? components.join("|") : components
|
|
87
|
+
end
|
|
88
|
+
unless (result_type = query.options[:result_type]).nil?
|
|
89
|
+
params[:result_type] = result_type.is_a?(Array) ? result_type.join("|") : result_type
|
|
90
|
+
end
|
|
91
|
+
params
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def query_url_params(query)
|
|
95
|
+
query_url_google_params(query).merge(
|
|
96
|
+
:key => configuration.api_key
|
|
97
|
+
).merge(super)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require "geocoder/lookups/google"
|
|
2
|
+
require "geocoder/results/google_places_details"
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Lookup
|
|
6
|
+
class GooglePlacesDetails < Google
|
|
7
|
+
def name
|
|
8
|
+
"Google Places Details"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def result_root_attr
|
|
26
|
+
'result'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def results(query)
|
|
30
|
+
result = super(query)
|
|
31
|
+
return [result] unless result.is_a? Array
|
|
32
|
+
|
|
33
|
+
result
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def fields(query)
|
|
37
|
+
if query.options.has_key?(:fields)
|
|
38
|
+
return format_fields(query.options[:fields])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if configuration.has_key?(:fields)
|
|
42
|
+
return format_fields(configuration[:fields])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
nil # use Google Places defaults
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def format_fields(*fields)
|
|
49
|
+
flattened = fields.flatten.compact
|
|
50
|
+
return if flattened.empty?
|
|
51
|
+
|
|
52
|
+
flattened.join(',')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def query_url_google_params(query)
|
|
56
|
+
{
|
|
57
|
+
placeid: query.text,
|
|
58
|
+
fields: fields(query),
|
|
59
|
+
language: query.language || configuration.language
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "geocoder/lookups/google"
|
|
2
|
+
require "geocoder/results/google_places_search"
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Lookup
|
|
6
|
+
class GooglePlacesSearch < Google
|
|
7
|
+
def name
|
|
8
|
+
"Google Places Search"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def result_root_attr
|
|
22
|
+
'candidates'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def base_query_url(query)
|
|
26
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def query_url_google_params(query)
|
|
30
|
+
{
|
|
31
|
+
input: query.text,
|
|
32
|
+
inputtype: 'textquery',
|
|
33
|
+
fields: fields(query),
|
|
34
|
+
locationbias: locationbias(query),
|
|
35
|
+
language: query.language || configuration.language
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def fields(query)
|
|
40
|
+
if query.options.has_key?(:fields)
|
|
41
|
+
return format_fields(query.options[:fields])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if configuration.has_key?(:fields)
|
|
45
|
+
return format_fields(configuration[:fields])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
default_fields
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def default_fields
|
|
52
|
+
basic = %w[business_status formatted_address geometry icon name
|
|
53
|
+
photos place_id plus_code types]
|
|
54
|
+
contact = %w[opening_hours]
|
|
55
|
+
atmosphere = %W[price_level rating user_ratings_total]
|
|
56
|
+
format_fields(basic, contact, atmosphere)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def format_fields(*fields)
|
|
60
|
+
flattened = fields.flatten.compact
|
|
61
|
+
return if flattened.empty?
|
|
62
|
+
|
|
63
|
+
flattened.join(',')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def locationbias(query)
|
|
67
|
+
if query.options.has_key?(:locationbias)
|
|
68
|
+
query.options[:locationbias]
|
|
69
|
+
else
|
|
70
|
+
configuration[:locationbias]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|