really-broken-geocoder 1.5.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/CHANGELOG.md +557 -0
- data/LICENSE +20 -0
- data/README.md +3 -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 +22 -0
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -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/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder.rb +48 -0
- data/lib/geocoder/cache.rb +94 -0
- data/lib/geocoder/calculations.rb +420 -0
- data/lib/geocoder/cli.rb +121 -0
- data/lib/geocoder/configuration.rb +137 -0
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +40 -0
- data/lib/geocoder/ip_address.rb +26 -0
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +118 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/baidu.rb +63 -0
- data/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +130 -0
- data/lib/geocoder/lookups/base.rb +348 -0
- data/lib/geocoder/lookups/bing.rb +82 -0
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +22 -0
- data/lib/geocoder/lookups/esri.rb +95 -0
- data/lib/geocoder/lookups/freegeoip.rb +60 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/lib/geocoder/lookups/geocoder_us.rb +51 -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 +95 -0
- data/lib/geocoder/lookups/google_places_details.rb +50 -0
- data/lib/geocoder/lookups/google_places_search.rb +33 -0
- data/lib/geocoder/lookups/google_premier.rb +57 -0
- data/lib/geocoder/lookups/here.rb +77 -0
- data/lib/geocoder/lookups/ip2location.rb +75 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +59 -0
- data/lib/geocoder/lookups/location_iq.rb +50 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +58 -0
- data/lib/geocoder/lookups/maxmind.rb +90 -0
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +65 -0
- data/lib/geocoder/lookups/nominatim.rb +64 -0
- data/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +69 -0
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +63 -0
- data/lib/geocoder/lookups/telize.rb +75 -0
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +44 -0
- data/lib/geocoder/lookups/yandex.rb +62 -0
- data/lib/geocoder/models/active_record.rb +51 -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 +125 -0
- data/lib/geocoder/railtie.rb +26 -0
- data/lib/geocoder/request.rb +114 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +79 -0
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/ban_data_gouv_fr.rb +257 -0
- data/lib/geocoder/results/base.rb +79 -0
- data/lib/geocoder/results/bing.rb +52 -0
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/dstk.rb +6 -0
- data/lib/geocoder/results/esri.rb +75 -0
- data/lib/geocoder/results/freegeoip.rb +40 -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 +78 -0
- data/lib/geocoder/results/geoip2.rb +76 -0
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +150 -0
- data/lib/geocoder/results/google_places_details.rb +39 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/google_premier.rb +6 -0
- data/lib/geocoder/results/here.rb +79 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +57 -0
- data/lib/geocoder/results/mapquest.rb +48 -0
- data/lib/geocoder/results/maxmind.rb +130 -0
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +44 -0
- data/lib/geocoder/results/nominatim.rb +109 -0
- data/lib/geocoder/results/opencagedata.rb +100 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +40 -0
- data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +142 -0
- data/lib/geocoder/results/telize.rb +40 -0
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +33 -0
- data/lib/geocoder/results/yandex.rb +134 -0
- data/lib/geocoder/sql.rb +110 -0
- data/lib/geocoder/stores/active_record.rb +328 -0
- data/lib/geocoder/stores/base.rb +115 -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 +54 -0
- data/lib/tasks/maxmind.rake +73 -0
- metadata +186 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipapi_com'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class IpapiCom < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"ip-api.com"
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_protocols
|
12
|
+
if configuration.api_key
|
13
|
+
[:http, :https]
|
14
|
+
else
|
15
|
+
[:http]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private # ----------------------------------------------------------------
|
20
|
+
|
21
|
+
def base_query_url(query)
|
22
|
+
domain = configuration.api_key ? "pro.ip-api.com" : "ip-api.com"
|
23
|
+
url = "#{protocol}://#{domain}/json/#{query.sanitized_text}"
|
24
|
+
url << "?" if not url_query_string(query).empty?
|
25
|
+
url
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_raw_data(raw_data)
|
29
|
+
if raw_data.chomp == "invalid key"
|
30
|
+
invalid_key_result
|
31
|
+
else
|
32
|
+
super(raw_data)
|
33
|
+
end
|
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
|
+
|
40
|
+
return [] unless doc = fetch_data(query)
|
41
|
+
|
42
|
+
if doc["message"] == "invalid key"
|
43
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
|
44
|
+
return []
|
45
|
+
else
|
46
|
+
return [doc]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reserved_result(query)
|
51
|
+
{
|
52
|
+
"message" => "reserved range",
|
53
|
+
"query" => query,
|
54
|
+
"status" => "fail",
|
55
|
+
"ip" => query,
|
56
|
+
"city" => "",
|
57
|
+
"region_code" => "",
|
58
|
+
"region_name" => "",
|
59
|
+
"metrocode" => "",
|
60
|
+
"zipcode" => "",
|
61
|
+
"latitude" => "0",
|
62
|
+
"longitude" => "0",
|
63
|
+
"country_name" => "Reserved",
|
64
|
+
"country_code" => "RD"
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def invalid_key_result
|
69
|
+
{
|
70
|
+
"message" => "invalid key"
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def query_url_params(query)
|
75
|
+
params = {}
|
76
|
+
params.merge!(fields: configuration[:fields]) if configuration.has_key?(:fields)
|
77
|
+
params.merge!(key: configuration.api_key) if configuration.api_key
|
78
|
+
params.merge(super)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipdata_co'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class IpdataCo < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"ipdata.co"
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_protocols
|
12
|
+
[:https]
|
13
|
+
end
|
14
|
+
|
15
|
+
def query_url(query)
|
16
|
+
# Ipdata.co requires that the API key be sent as a query parameter.
|
17
|
+
# It no longer supports API keys sent as headers.
|
18
|
+
"#{protocol}://#{host}/#{query.sanitized_text}?api-key=#{configuration.api_key}"
|
19
|
+
end
|
20
|
+
|
21
|
+
private # ---------------------------------------------------------------
|
22
|
+
|
23
|
+
def cache_key(query)
|
24
|
+
query_url(query)
|
25
|
+
end
|
26
|
+
|
27
|
+
def results(query)
|
28
|
+
# don't look up a loopback or private address, just return the stored result
|
29
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
30
|
+
# note: Ipdata.co returns plain text on bad request
|
31
|
+
(doc = fetch_data(query)) ? [doc] : []
|
32
|
+
end
|
33
|
+
|
34
|
+
def reserved_result(ip)
|
35
|
+
{
|
36
|
+
"ip" => ip,
|
37
|
+
"city" => "",
|
38
|
+
"region_code" => "",
|
39
|
+
"region_name" => "",
|
40
|
+
"metrocode" => "",
|
41
|
+
"zipcode" => "",
|
42
|
+
"latitude" => "0",
|
43
|
+
"longitude" => "0",
|
44
|
+
"country_name" => "Reserved",
|
45
|
+
"country_code" => "RD"
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def host
|
50
|
+
"api.ipdata.co"
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_response_for_errors!(response)
|
54
|
+
if response.code.to_i == 403
|
55
|
+
raise_error(Geocoder::RequestDenied) ||
|
56
|
+
Geocoder.log(:warn, "Geocoding API error: 403 API key does not exist")
|
57
|
+
else
|
58
|
+
super(response)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipinfo_io'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class IpinfoIo < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Ipinfo.io"
|
9
|
+
end
|
10
|
+
|
11
|
+
private # ---------------------------------------------------------------
|
12
|
+
|
13
|
+
def base_query_url(query)
|
14
|
+
url = "#{protocol}://ipinfo.io/#{query.sanitized_text}/geo"
|
15
|
+
url << "?" if configuration.api_key
|
16
|
+
url
|
17
|
+
end
|
18
|
+
|
19
|
+
def results(query)
|
20
|
+
# don't look up a loopback or private address, just return the stored result
|
21
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
22
|
+
|
23
|
+
if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
|
24
|
+
[]
|
25
|
+
else
|
26
|
+
[doc]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def reserved_result(ip)
|
31
|
+
{
|
32
|
+
"ip" => ip,
|
33
|
+
"bogon" => true
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def query_url_params(query)
|
38
|
+
{
|
39
|
+
token: configuration.api_key
|
40
|
+
}.merge(super)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipstack'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Ipstack < Base
|
6
|
+
|
7
|
+
ERROR_CODES = {
|
8
|
+
404 => Geocoder::InvalidRequest,
|
9
|
+
101 => Geocoder::InvalidApiKey,
|
10
|
+
102 => Geocoder::Error,
|
11
|
+
103 => Geocoder::InvalidRequest,
|
12
|
+
104 => Geocoder::OverQueryLimitError,
|
13
|
+
105 => Geocoder::RequestDenied,
|
14
|
+
301 => Geocoder::InvalidRequest,
|
15
|
+
302 => Geocoder::InvalidRequest,
|
16
|
+
303 => Geocoder::RequestDenied,
|
17
|
+
}
|
18
|
+
ERROR_CODES.default = Geocoder::Error
|
19
|
+
|
20
|
+
def name
|
21
|
+
"Ipstack"
|
22
|
+
end
|
23
|
+
|
24
|
+
private # ----------------------------------------------------------------
|
25
|
+
|
26
|
+
def base_query_url(query)
|
27
|
+
"#{protocol}://#{host}/#{query.sanitized_text}?"
|
28
|
+
end
|
29
|
+
|
30
|
+
def query_url_params(query)
|
31
|
+
{
|
32
|
+
access_key: configuration.api_key
|
33
|
+
}.merge(super)
|
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
|
+
|
40
|
+
return [] unless doc = fetch_data(query)
|
41
|
+
|
42
|
+
if error = doc['error']
|
43
|
+
code = error['code']
|
44
|
+
msg = error['info']
|
45
|
+
raise_error(ERROR_CODES[code], msg ) || Geocoder.log(:warn, "Ipstack Geocoding API error: #{msg}")
|
46
|
+
return []
|
47
|
+
end
|
48
|
+
[doc]
|
49
|
+
end
|
50
|
+
|
51
|
+
def reserved_result(ip)
|
52
|
+
{
|
53
|
+
"ip" => ip,
|
54
|
+
"country_name" => "Reserved",
|
55
|
+
"country_code" => "RD"
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def host
|
60
|
+
configuration[:host] || "api.ipstack.com"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/latlon'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Latlon < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"LatLon.io"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
["api_key"]
|
13
|
+
end
|
14
|
+
|
15
|
+
private # ---------------------------------------------------------------
|
16
|
+
|
17
|
+
def base_query_url(query)
|
18
|
+
"#{protocol}://latlon.io/api/v1/#{'reverse_' if query.reverse_geocode?}geocode?"
|
19
|
+
end
|
20
|
+
|
21
|
+
def results(query)
|
22
|
+
return [] unless doc = fetch_data(query)
|
23
|
+
if doc['error'].nil?
|
24
|
+
[doc]
|
25
|
+
# The API returned a 404 response, which indicates no results found
|
26
|
+
elsif doc['error']['type'] == 'api_error'
|
27
|
+
[]
|
28
|
+
elsif
|
29
|
+
doc['error']['type'] == 'authentication_error'
|
30
|
+
raise_error(Geocoder::InvalidApiKey) ||
|
31
|
+
Geocoder.log(:warn, "LatLon.io service error: invalid API key.")
|
32
|
+
else
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def supported_protocols
|
38
|
+
[:https]
|
39
|
+
end
|
40
|
+
|
41
|
+
private # ---------------------------------------------------------------
|
42
|
+
|
43
|
+
def query_url_params(query)
|
44
|
+
if query.reverse_geocode?
|
45
|
+
{
|
46
|
+
:token => configuration.api_key,
|
47
|
+
:lat => query.coordinates[0],
|
48
|
+
:lon => query.coordinates[1]
|
49
|
+
}.merge(super)
|
50
|
+
else
|
51
|
+
{
|
52
|
+
:token => configuration.api_key,
|
53
|
+
:address => query.sanitized_text
|
54
|
+
}.merge(super)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'geocoder/lookups/nominatim'
|
2
|
+
require "geocoder/results/location_iq"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class LocationIq < Nominatim
|
6
|
+
def name
|
7
|
+
"LocationIq"
|
8
|
+
end
|
9
|
+
|
10
|
+
def required_api_key_parts
|
11
|
+
["api_key"]
|
12
|
+
end
|
13
|
+
|
14
|
+
private # ----------------------------------------------------------------
|
15
|
+
|
16
|
+
def base_query_url(query)
|
17
|
+
method = query.reverse_geocode? ? "reverse" : "search"
|
18
|
+
"#{protocol}://#{configured_host}/v1/#{method}.php?"
|
19
|
+
end
|
20
|
+
|
21
|
+
def query_url_params(query)
|
22
|
+
{
|
23
|
+
key: configuration.api_key
|
24
|
+
}.merge(super)
|
25
|
+
end
|
26
|
+
|
27
|
+
def configured_host
|
28
|
+
configuration[:host] || "locationiq.org"
|
29
|
+
end
|
30
|
+
|
31
|
+
def results(query)
|
32
|
+
return [] unless doc = fetch_data(query)
|
33
|
+
|
34
|
+
if !doc.is_a?(Array)
|
35
|
+
case doc['error']
|
36
|
+
when "Invalid key"
|
37
|
+
raise_error(Geocoder::InvalidApiKey, doc['error'])
|
38
|
+
when "Key not active - Please write to contact@unwiredlabs.com"
|
39
|
+
raise_error(Geocoder::RequestDenied, doc['error'])
|
40
|
+
when "Rate Limited"
|
41
|
+
raise_error(Geocoder::OverQueryLimitError, doc['error'])
|
42
|
+
when "Unknown error - Please try again after some time"
|
43
|
+
raise_error(Geocoder::InvalidRequest, doc['error'])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
doc.is_a?(Array) ? doc : [doc]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/mapbox"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Mapbox < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Mapbox"
|
9
|
+
end
|
10
|
+
|
11
|
+
private # ---------------------------------------------------------------
|
12
|
+
|
13
|
+
def base_query_url(query)
|
14
|
+
"#{protocol}://api.mapbox.com/geocoding/v5/#{dataset}/#{mapbox_search_term(query)}.json?"
|
15
|
+
end
|
16
|
+
|
17
|
+
def results(query)
|
18
|
+
return [] unless data = fetch_data(query)
|
19
|
+
if data['features']
|
20
|
+
sort_relevant_feature(data['features'])
|
21
|
+
elsif data['message'] =~ /Invalid\sToken/
|
22
|
+
raise_error(Geocoder::InvalidApiKey, data['message'])
|
23
|
+
else
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def query_url_params(query)
|
29
|
+
{access_token: configuration.api_key}.merge(super(query))
|
30
|
+
end
|
31
|
+
|
32
|
+
def mapbox_search_term(query)
|
33
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
|
34
|
+
if query.reverse_geocode?
|
35
|
+
lat,lon = query.coordinates
|
36
|
+
"#{CGI.escape lon},#{CGI.escape lat}"
|
37
|
+
else
|
38
|
+
# truncate at first semicolon so Mapbox doesn't go into batch mode
|
39
|
+
# (see Github issue #1299)
|
40
|
+
CGI.escape query.text.to_s.split(';').first.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def dataset
|
45
|
+
configuration[:dataset] || "mapbox.places"
|
46
|
+
end
|
47
|
+
|
48
|
+
def supported_protocols
|
49
|
+
[:https]
|
50
|
+
end
|
51
|
+
|
52
|
+
def sort_relevant_feature(features)
|
53
|
+
# Sort by descending relevance; Favor original order for equal relevance (eg occurs for reverse geocoding)
|
54
|
+
features.sort_by do |feature|
|
55
|
+
[feature["relevance"],-features.index(feature)]
|
56
|
+
end.reverse
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'geocoder/lookups/base'
|
3
|
+
require "geocoder/results/mapquest"
|
4
|
+
|
5
|
+
module Geocoder::Lookup
|
6
|
+
class Mapquest < Base
|
7
|
+
|
8
|
+
def name
|
9
|
+
"Mapquest"
|
10
|
+
end
|
11
|
+
|
12
|
+
def required_api_key_parts
|
13
|
+
["key"]
|
14
|
+
end
|
15
|
+
|
16
|
+
private # ---------------------------------------------------------------
|
17
|
+
|
18
|
+
def base_query_url(query)
|
19
|
+
domain = configuration[:open] ? "open" : "www"
|
20
|
+
"#{protocol}://#{domain}.mapquestapi.com/geocoding/v1/#{search_type(query)}?"
|
21
|
+
end
|
22
|
+
|
23
|
+
def search_type(query)
|
24
|
+
query.reverse_geocode? ? "reverse" : "address"
|
25
|
+
end
|
26
|
+
|
27
|
+
def query_url_params(query)
|
28
|
+
params = { :location => query.sanitized_text }
|
29
|
+
if key = configuration.api_key
|
30
|
+
params[:key] = CGI.unescape(key)
|
31
|
+
end
|
32
|
+
params.merge(super)
|
33
|
+
end
|
34
|
+
|
35
|
+
# http://www.mapquestapi.com/geocoding/status_codes.html
|
36
|
+
# http://open.mapquestapi.com/geocoding/status_codes.html
|
37
|
+
def results(query)
|
38
|
+
return [] unless doc = fetch_data(query)
|
39
|
+
return doc["results"][0]['locations'] if doc['info']['statuscode'] == 0 # A successful geocode call
|
40
|
+
|
41
|
+
messages = doc['info']['messages'].join
|
42
|
+
|
43
|
+
case doc['info']['statuscode']
|
44
|
+
when 400 # Error with input
|
45
|
+
raise_error(Geocoder::InvalidRequest, messages) ||
|
46
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
47
|
+
when 403 # Key related error
|
48
|
+
raise_error(Geocoder::InvalidApiKey, messages) ||
|
49
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
50
|
+
when 500 # Unknown error
|
51
|
+
raise_error(Geocoder::Error, messages) ||
|
52
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
53
|
+
end
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|