geocoder 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of geocoder might be problematic. Click here for more details.
- data/.travis.yml +4 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +90 -37
- data/README.md +96 -45
- data/examples/autoexpire_cache.rb +1 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +18 -22
- data/lib/geocoder.rb +2 -4
- data/lib/geocoder/cache.rb +2 -1
- data/lib/geocoder/calculations.rb +12 -12
- data/lib/geocoder/cli.rb +10 -11
- data/lib/geocoder/configuration.rb +67 -43
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/exceptions.rb +3 -0
- data/lib/geocoder/lookup.rb +1 -1
- data/lib/geocoder/lookups/base.rb +59 -16
- data/lib/geocoder/lookups/bing.rb +21 -11
- data/lib/geocoder/lookups/freegeoip.rb +8 -4
- data/lib/geocoder/lookups/geocoder_ca.rb +11 -7
- data/lib/geocoder/lookups/google.rb +18 -9
- data/lib/geocoder/lookups/google_premier.rb +16 -8
- data/lib/geocoder/lookups/mapquest.rb +12 -5
- data/lib/geocoder/lookups/maxmind.rb +72 -0
- data/lib/geocoder/lookups/nominatim.rb +13 -8
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/yahoo.rb +38 -11
- data/lib/geocoder/lookups/yandex.rb +17 -9
- data/lib/geocoder/query.rb +17 -8
- data/lib/geocoder/request.rb +7 -1
- data/lib/geocoder/results/google.rb +6 -0
- data/lib/geocoder/results/maxmind.rb +136 -0
- data/lib/geocoder/results/nominatim.rb +0 -10
- data/lib/geocoder/sql.rb +6 -4
- data/lib/geocoder/stores/active_record.rb +5 -5
- data/lib/geocoder/stores/base.rb +3 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/oauth_util.rb +8 -2
- data/test/cache_test.rb +2 -2
- data/test/calculations_test.rb +4 -4
- data/test/configuration_test.rb +26 -51
- data/test/error_handling_test.rb +4 -4
- data/test/fixtures/bing_invalid_key +1 -0
- data/test/fixtures/{bing_madison_square_garden.json → bing_madison_square_garden} +0 -0
- data/test/fixtures/{bing_no_results.json → bing_no_results} +0 -0
- data/test/fixtures/{bing_reverse.json → bing_reverse} +0 -0
- data/test/fixtures/{freegeoip_74_200_247_59.json → freegeoip_74_200_247_59} +0 -0
- data/test/fixtures/{freegeoip_no_results.json → freegeoip_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_madison_square_garden.json → geocoder_ca_madison_square_garden} +0 -0
- data/test/fixtures/{geocoder_ca_no_results.json → geocoder_ca_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_reverse.json → geocoder_ca_reverse} +0 -0
- data/test/fixtures/{google_garbage.json → google_garbage} +0 -0
- data/test/fixtures/{google_madison_square_garden.json → google_madison_square_garden} +0 -0
- data/test/fixtures/{google_no_city_data.json → google_no_city_data} +0 -0
- data/test/fixtures/{google_no_locality.json → google_no_locality} +0 -0
- data/test/fixtures/{google_no_results.json → google_no_results} +0 -0
- data/test/fixtures/{mapquest_madison_square_garden.json → mapquest_madison_square_garden} +0 -0
- data/test/fixtures/{mapquest_no_results.json → mapquest_no_results} +0 -0
- data/test/fixtures/maxmind_24_24_24_21 +1 -0
- data/test/fixtures/maxmind_24_24_24_22 +1 -0
- data/test/fixtures/maxmind_24_24_24_23 +1 -0
- data/test/fixtures/maxmind_24_24_24_24 +1 -0
- data/test/fixtures/maxmind_74_200_247_59 +1 -0
- data/test/fixtures/maxmind_invalid_key +1 -0
- data/test/fixtures/maxmind_no_results +1 -0
- data/test/fixtures/{nominatim_madison_square_garden.json → nominatim_madison_square_garden} +0 -0
- data/test/fixtures/{nominatim_no_results.json → nominatim_no_results} +0 -0
- data/test/fixtures/{yahoo_error.json → yahoo_error} +0 -0
- data/test/fixtures/yahoo_invalid_key +2 -0
- data/test/fixtures/{yahoo_madison_square_garden.json → yahoo_madison_square_garden} +0 -0
- data/test/fixtures/{yahoo_no_results.json → yahoo_no_results} +0 -0
- data/test/fixtures/yahoo_over_limit +2 -0
- data/test/fixtures/{yandex_invalid_key.json → yandex_invalid_key} +0 -0
- data/test/fixtures/{yandex_kremlin.json → yandex_kremlin} +0 -0
- data/test/fixtures/{yandex_no_results.json → yandex_no_results} +0 -0
- data/test/https_test.rb +3 -3
- data/test/integration/smoke_test.rb +2 -2
- data/test/lookup_test.rb +82 -5
- data/test/oauth_util_test.rb +30 -0
- data/test/proxy_test.rb +2 -2
- data/test/query_test.rb +3 -0
- data/test/result_test.rb +2 -2
- data/test/services_test.rb +121 -44
- data/test/test_helper.rb +44 -109
- data/test/test_mode_test.rb +3 -3
- metadata +42 -33
@@ -4,34 +4,44 @@ require "geocoder/results/bing"
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class Bing < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"Bing"
|
9
|
+
end
|
10
|
+
|
7
11
|
def map_link_url(coordinates)
|
8
12
|
"http://www.bing.com/maps/default.aspx?cp=#{coordinates.join('~')}"
|
9
13
|
end
|
10
14
|
|
15
|
+
def required_api_key_parts
|
16
|
+
["key"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def query_url(query)
|
20
|
+
"#{protocol}://dev.virtualearth.net/REST/v1/Locations" +
|
21
|
+
(query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?") +
|
22
|
+
url_query_string(query)
|
23
|
+
end
|
24
|
+
|
11
25
|
private # ---------------------------------------------------------------
|
12
26
|
|
13
27
|
def results(query)
|
14
28
|
return [] unless doc = fetch_data(query)
|
15
29
|
|
16
|
-
if doc['
|
30
|
+
if doc['statusCode'] == 200
|
17
31
|
return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : []
|
32
|
+
elsif doc['statusCode'] == 401 and doc["authenticationResultCode"] == "InvalidCredentials"
|
33
|
+
raise_error(Geocoder::InvalidApiKey) || warn("Invalid Bing API key.")
|
18
34
|
else
|
19
35
|
warn "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']})."
|
20
|
-
return []
|
21
36
|
end
|
37
|
+
return []
|
22
38
|
end
|
23
39
|
|
24
40
|
def query_url_params(query)
|
25
|
-
|
26
|
-
:key =>
|
41
|
+
{
|
42
|
+
:key => configuration.api_key,
|
27
43
|
:query => query.reverse_geocode? ? nil : query.sanitized_text
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
def query_url(query)
|
32
|
-
"#{protocol}://dev.virtualearth.net/REST/v1/Locations" +
|
33
|
-
(query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?") +
|
34
|
-
url_query_string(query)
|
44
|
+
}.merge(super)
|
35
45
|
end
|
36
46
|
end
|
37
47
|
end
|
@@ -4,6 +4,14 @@ require 'geocoder/results/freegeoip'
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class Freegeoip < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"FreeGeoIP"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_url(query)
|
12
|
+
"#{protocol}://freegeoip.net/json/#{query.sanitized_text}"
|
13
|
+
end
|
14
|
+
|
7
15
|
private # ---------------------------------------------------------------
|
8
16
|
|
9
17
|
def parse_raw_data(raw_data)
|
@@ -35,9 +43,5 @@ module Geocoder::Lookup
|
|
35
43
|
"country_code" => "RD"
|
36
44
|
}
|
37
45
|
end
|
38
|
-
|
39
|
-
def query_url(query)
|
40
|
-
"#{protocol}://freegeoip.net/json/#{query.sanitized_text}"
|
41
|
-
end
|
42
46
|
end
|
43
47
|
end
|
@@ -4,6 +4,14 @@ require "geocoder/results/geocoder_ca"
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class GeocoderCa < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"Geocoder.ca"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_url(query)
|
12
|
+
"#{protocol}://geocoder.ca/?" + url_query_string(query)
|
13
|
+
end
|
14
|
+
|
7
15
|
private # ---------------------------------------------------------------
|
8
16
|
|
9
17
|
def results(query)
|
@@ -19,12 +27,12 @@ module Geocoder::Lookup
|
|
19
27
|
end
|
20
28
|
|
21
29
|
def query_url_params(query)
|
22
|
-
params =
|
30
|
+
params = {
|
23
31
|
:geoit => "xml",
|
24
32
|
:jsonp => 1,
|
25
33
|
:callback => "test",
|
26
|
-
:auth =>
|
27
|
-
)
|
34
|
+
:auth => configuration.api_key
|
35
|
+
}.merge(super)
|
28
36
|
if query.reverse_geocode?
|
29
37
|
lat,lon = query.coordinates
|
30
38
|
params[:latt] = lat
|
@@ -38,10 +46,6 @@ module Geocoder::Lookup
|
|
38
46
|
params
|
39
47
|
end
|
40
48
|
|
41
|
-
def query_url(query)
|
42
|
-
"#{protocol}://geocoder.ca/?" + url_query_string(query)
|
43
|
-
end
|
44
|
-
|
45
49
|
def parse_raw_data(raw_data)
|
46
50
|
super raw_data[/^test\((.*)\)\;\s*$/, 1]
|
47
51
|
end
|
@@ -4,10 +4,18 @@ require "geocoder/results/google"
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class Google < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"Google"
|
9
|
+
end
|
10
|
+
|
7
11
|
def map_link_url(coordinates)
|
8
12
|
"http://maps.google.com/maps?q=#{coordinates.join(',')}"
|
9
13
|
end
|
10
14
|
|
15
|
+
def query_url(query)
|
16
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + url_query_string(query)
|
17
|
+
end
|
18
|
+
|
11
19
|
private # ---------------------------------------------------------------
|
12
20
|
|
13
21
|
def results(query)
|
@@ -31,23 +39,24 @@ module Geocoder::Lookup
|
|
31
39
|
params = {
|
32
40
|
(query.reverse_geocode? ? :latlng : :address) => query.sanitized_text,
|
33
41
|
:sensor => "false",
|
34
|
-
:language =>
|
42
|
+
:language => configuration.language
|
35
43
|
}
|
36
44
|
unless (bounds = query.options[:bounds]).nil?
|
37
45
|
params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join('|')
|
38
46
|
end
|
47
|
+
unless (region = query.options[:region]).nil?
|
48
|
+
params[:region] = region
|
49
|
+
end
|
50
|
+
unless (components = query.options[:components]).nil?
|
51
|
+
params[:components] = components.is_a?(Array) ? components.join("|") : components
|
52
|
+
end
|
39
53
|
params
|
40
54
|
end
|
41
55
|
|
42
56
|
def query_url_params(query)
|
43
|
-
|
44
|
-
:key =>
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
def query_url(query)
|
49
|
-
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + url_query_string(query)
|
57
|
+
query_url_google_params(query).merge(
|
58
|
+
:key => configuration.api_key
|
59
|
+
).merge(super)
|
50
60
|
end
|
51
61
|
end
|
52
62
|
end
|
53
|
-
|
@@ -6,14 +6,12 @@ require 'geocoder/results/google_premier'
|
|
6
6
|
module Geocoder::Lookup
|
7
7
|
class GooglePremier < Google
|
8
8
|
|
9
|
-
|
9
|
+
def name
|
10
|
+
"Google Premier"
|
11
|
+
end
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
-
:key => nil, # don't use param inherited from Google lookup
|
14
|
-
:client => Geocoder::Configuration.api_key[1],
|
15
|
-
:channel => Geocoder::Configuration.api_key[2]
|
16
|
-
)
|
13
|
+
def required_api_key_parts
|
14
|
+
["private key", "client", "channel"]
|
17
15
|
end
|
18
16
|
|
19
17
|
def query_url(query)
|
@@ -21,8 +19,18 @@ module Geocoder::Lookup
|
|
21
19
|
"#{protocol}://maps.googleapis.com#{path}&signature=#{sign(path)}"
|
22
20
|
end
|
23
21
|
|
22
|
+
private # ---------------------------------------------------------------
|
23
|
+
|
24
|
+
def query_url_params(query)
|
25
|
+
query_url_google_params(query).merge(super).merge(
|
26
|
+
:key => nil, # don't use param inherited from Google lookup
|
27
|
+
:client => configuration.api_key[1],
|
28
|
+
:channel => configuration.api_key[2]
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
24
32
|
def sign(string)
|
25
|
-
raw_private_key = url_safe_base64_decode(
|
33
|
+
raw_private_key = url_safe_base64_decode(configuration.api_key[0])
|
26
34
|
digest = OpenSSL::Digest::Digest.new('sha1')
|
27
35
|
raw_signature = OpenSSL::HMAC.digest(digest, raw_private_key, string)
|
28
36
|
url_safe_base64_encode(raw_signature)
|
@@ -5,26 +5,33 @@ require "geocoder/results/mapquest"
|
|
5
5
|
module Geocoder::Lookup
|
6
6
|
class Mapquest < Base
|
7
7
|
|
8
|
-
|
8
|
+
def name
|
9
|
+
"Mapquest"
|
10
|
+
end
|
11
|
+
|
12
|
+
def required_api_key_parts
|
13
|
+
["key"]
|
14
|
+
end
|
9
15
|
|
10
16
|
def query_url(query)
|
11
|
-
key =
|
17
|
+
key = configuration.api_key
|
12
18
|
domain = key ? "www" : "open"
|
13
19
|
url = "#{protocol}://#{domain}.mapquestapi.com/geocoding/v1/#{search_type(query)}?"
|
14
20
|
url + url_query_string(query)
|
15
21
|
end
|
16
22
|
|
23
|
+
private # ---------------------------------------------------------------
|
24
|
+
|
17
25
|
def search_type(query)
|
18
26
|
query.reverse_geocode? ? "reverse" : "address"
|
19
27
|
end
|
20
28
|
|
21
29
|
def query_url_params(query)
|
22
|
-
key = Geocoder::Configuration.api_key
|
23
30
|
params = { :location => query.sanitized_text }
|
24
|
-
if key
|
31
|
+
if key = configuration.api_key
|
25
32
|
params[:key] = CGI.unescape(key)
|
26
33
|
end
|
27
|
-
|
34
|
+
params.merge(super)
|
28
35
|
end
|
29
36
|
|
30
37
|
def results(query)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/maxmind'
|
3
|
+
require 'csv'
|
4
|
+
|
5
|
+
module Geocoder::Lookup
|
6
|
+
class Maxmind < Base
|
7
|
+
|
8
|
+
def name
|
9
|
+
"MaxMind"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_url(query)
|
13
|
+
"#{protocol}://geoip.maxmind.com/#{service_code}?" + url_query_string(query)
|
14
|
+
end
|
15
|
+
|
16
|
+
private # ---------------------------------------------------------------
|
17
|
+
|
18
|
+
def service_code
|
19
|
+
if s = configuration[:service] and services.keys.include?(s)
|
20
|
+
services[s]
|
21
|
+
else
|
22
|
+
raise(
|
23
|
+
Geocoder::ConfigurationError,
|
24
|
+
"When using MaxMind you MUST specify a service name: " +
|
25
|
+
"Geocoder.configure(:maxmind => {:service => ...}), " +
|
26
|
+
"where '...' is one of: #{services.keys.inspect}"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Service names mapped to code used in URL.
|
33
|
+
#
|
34
|
+
def services
|
35
|
+
{
|
36
|
+
:country => "a",
|
37
|
+
:city => "b",
|
38
|
+
:city_isp_org => "f",
|
39
|
+
:omni => "e"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def results(query)
|
44
|
+
# don't look up a loopback address, just return the stored result
|
45
|
+
return [reserved_result] if query.loopback_ip_address?
|
46
|
+
doc = fetch_data(query)
|
47
|
+
if doc and doc.is_a?(Array)
|
48
|
+
if doc.last.nil?
|
49
|
+
return [doc]
|
50
|
+
elsif doc.last == "INVALID_LICENSE_KEY"
|
51
|
+
raise_error(Geocoder::InvalidApiKey) || warn("Invalid MaxMind API key.")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
return []
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_raw_data(raw_data)
|
58
|
+
CSV.parse_line raw_data
|
59
|
+
end
|
60
|
+
|
61
|
+
def reserved_result
|
62
|
+
",,,,0,0,0,0,,,"
|
63
|
+
end
|
64
|
+
|
65
|
+
def query_url_params(query)
|
66
|
+
{
|
67
|
+
:l => configuration.api_key,
|
68
|
+
:i => query.sanitized_text
|
69
|
+
}.merge(super)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -4,10 +4,20 @@ require "geocoder/results/nominatim"
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class Nominatim < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"Nominatim"
|
9
|
+
end
|
10
|
+
|
7
11
|
def map_link_url(coordinates)
|
8
12
|
"http://www.openstreetmap.org/?lat=#{coordinates[0]}&lon=#{coordinates[1]}&zoom=15&layers=M"
|
9
13
|
end
|
10
14
|
|
15
|
+
def query_url(query)
|
16
|
+
method = query.reverse_geocode? ? "reverse" : "search"
|
17
|
+
host = configuration[:host] || "nominatim.openstreetmap.org"
|
18
|
+
"#{protocol}://#{host}/#{method}?" + url_query_string(query)
|
19
|
+
end
|
20
|
+
|
11
21
|
private # ---------------------------------------------------------------
|
12
22
|
|
13
23
|
def results(query)
|
@@ -16,12 +26,12 @@ module Geocoder::Lookup
|
|
16
26
|
end
|
17
27
|
|
18
28
|
def query_url_params(query)
|
19
|
-
params =
|
29
|
+
params = {
|
20
30
|
:format => "json",
|
21
31
|
:polygon => "1",
|
22
32
|
:addressdetails => "1",
|
23
|
-
:"accept-language" =>
|
24
|
-
)
|
33
|
+
:"accept-language" => configuration.language
|
34
|
+
}.merge(super)
|
25
35
|
if query.reverse_geocode?
|
26
36
|
lat,lon = query.coordinates
|
27
37
|
params[:lat] = lat
|
@@ -31,10 +41,5 @@ module Geocoder::Lookup
|
|
31
41
|
end
|
32
42
|
params
|
33
43
|
end
|
34
|
-
|
35
|
-
def query_url(query)
|
36
|
-
method = query.reverse_geocode? ? "reverse" : "search"
|
37
|
-
"#{protocol}://nominatim.openstreetmap.org/#{method}?" + url_query_string(query)
|
38
|
-
end
|
39
44
|
end
|
40
45
|
end
|
@@ -5,10 +5,26 @@ require 'oauth_util'
|
|
5
5
|
module Geocoder::Lookup
|
6
6
|
class Yahoo < Base
|
7
7
|
|
8
|
+
def name
|
9
|
+
"Yahoo BOSS"
|
10
|
+
end
|
11
|
+
|
8
12
|
def map_link_url(coordinates)
|
9
13
|
"http://maps.yahoo.com/#lat=#{coordinates[0]}&lon=#{coordinates[1]}"
|
10
14
|
end
|
11
15
|
|
16
|
+
def required_api_key_parts
|
17
|
+
["consumer key", "consumer secret"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def query_url(query)
|
21
|
+
parsed_url = URI.parse(raw_url(query))
|
22
|
+
o = OauthUtil.new
|
23
|
+
o.consumer_key = configuration.api_key[0]
|
24
|
+
o.consumer_secret = configuration.api_key[1]
|
25
|
+
base_url + o.sign(parsed_url).query_string
|
26
|
+
end
|
27
|
+
|
12
28
|
private # ---------------------------------------------------------------
|
13
29
|
|
14
30
|
def results(query)
|
@@ -26,12 +42,31 @@ module Geocoder::Lookup
|
|
26
42
|
end
|
27
43
|
end
|
28
44
|
|
45
|
+
##
|
46
|
+
# Yahoo returns errors as XML even when JSON format is specified.
|
47
|
+
# Handle that here, without parsing the XML
|
48
|
+
# (which would add unnecessary complexity).
|
49
|
+
#
|
50
|
+
def parse_raw_data(raw_data)
|
51
|
+
if raw_data.match /^<\?xml/
|
52
|
+
if raw_data.include?("Rate Limit Exceeded")
|
53
|
+
raise_error(Geocoder::OverQueryLimitError) || warn("Over API query limit.")
|
54
|
+
elsif raw_data.include?("Please provide valid credentials")
|
55
|
+
raise_error(Geocoder::InvalidApiKey) || warn("Invalid API key.")
|
56
|
+
end
|
57
|
+
else
|
58
|
+
super(raw_data)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
29
62
|
def query_url_params(query)
|
30
|
-
|
63
|
+
{
|
31
64
|
:location => query.sanitized_text,
|
32
65
|
:flags => "JXTSR",
|
33
|
-
:gflags => "AC#{'R' if query.reverse_geocode?}"
|
34
|
-
|
66
|
+
:gflags => "AC#{'R' if query.reverse_geocode?}",
|
67
|
+
:locale => "#{configuration.language}_US",
|
68
|
+
:appid => configuration.api_key
|
69
|
+
}.merge(super)
|
35
70
|
end
|
36
71
|
|
37
72
|
def cache_key(query)
|
@@ -45,13 +80,5 @@ module Geocoder::Lookup
|
|
45
80
|
def raw_url(query)
|
46
81
|
base_url + url_query_string(query)
|
47
82
|
end
|
48
|
-
|
49
|
-
def query_url(query)
|
50
|
-
parsed_url = URI.parse(raw_url(query))
|
51
|
-
o = OauthUtil.new
|
52
|
-
o.consumer_key = Geocoder::Configuration.api_key[0]
|
53
|
-
o.consumer_secret = Geocoder::Configuration.api_key[1]
|
54
|
-
base_url + o.sign(parsed_url).query_string
|
55
|
-
end
|
56
83
|
end
|
57
84
|
end
|