geocoder 1.1.9 → 1.2.0
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.
Potentially problematic release.
This version of geocoder might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +9 -5
- data/CHANGELOG.md +19 -0
- data/README.md +175 -10
- data/Rakefile +1 -1
- data/gemfiles/Gemfile.mongoid-2.4.x +1 -0
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +28 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +28 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +27 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/lib/geocoder.rb +4 -12
- data/lib/geocoder/cache.rb +3 -2
- data/lib/geocoder/calculations.rb +39 -0
- data/lib/geocoder/configuration.rb +1 -7
- data/lib/geocoder/ip_address.rb +12 -0
- data/lib/geocoder/lookup.rb +10 -1
- data/lib/geocoder/lookups/baidu.rb +7 -6
- data/lib/geocoder/lookups/baidu_ip.rb +54 -0
- data/lib/geocoder/lookups/base.rb +37 -9
- data/lib/geocoder/lookups/bing.rb +10 -5
- data/lib/geocoder/lookups/cloudmade.rb +35 -0
- data/lib/geocoder/lookups/freegeoip.rb +5 -1
- data/lib/geocoder/lookups/geocodio.rb +42 -0
- data/lib/geocoder/lookups/google_premier.rb +1 -1
- data/lib/geocoder/lookups/here.rb +62 -0
- data/lib/geocoder/lookups/mapquest.rb +2 -1
- data/lib/geocoder/lookups/maxmind_local.rb +58 -0
- data/lib/geocoder/lookups/nominatim.rb +8 -0
- data/lib/geocoder/lookups/smarty_streets.rb +45 -0
- data/lib/geocoder/lookups/yahoo.rb +1 -1
- data/lib/geocoder/models/active_record.rb +5 -3
- data/lib/geocoder/models/base.rb +1 -4
- data/lib/geocoder/models/mongo_base.rb +4 -2
- data/lib/geocoder/query.rb +4 -4
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/request.rb +10 -8
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/cloudmade.rb +39 -0
- data/lib/geocoder/results/geocodio.rb +66 -0
- data/lib/geocoder/results/here.rb +62 -0
- data/lib/geocoder/results/maxmind_local.rb +49 -0
- data/lib/geocoder/results/smarty_streets.rb +106 -0
- data/lib/geocoder/results/test.rb +20 -3
- data/lib/geocoder/results/yandex.rb +7 -3
- data/lib/geocoder/sql.rb +16 -15
- data/lib/geocoder/stores/active_record.rb +6 -2
- data/lib/geocoder/stores/base.rb +8 -1
- data/lib/geocoder/version.rb +1 -1
- data/lib/maxmind_database.rb +109 -0
- data/lib/oauth_util.rb +1 -1
- data/lib/tasks/geocoder.rake +3 -1
- data/lib/tasks/maxmind.rake +73 -0
- data/test/fixtures/baidu_ip_202_198_16_3 +19 -0
- data/test/fixtures/baidu_ip_invalid_key +1 -0
- data/test/fixtures/baidu_ip_no_results +1 -0
- data/test/fixtures/cloudmade_invalid_key +1 -0
- data/test/fixtures/cloudmade_madison_square_garden +1 -0
- data/test/fixtures/cloudmade_no_results +1 -0
- data/test/fixtures/geocodio_1101_pennsylvania_ave +1 -0
- data/test/fixtures/geocodio_bad_api_key +3 -0
- data/test/fixtures/geocodio_invalid +4 -0
- data/test/fixtures/geocodio_no_results +1 -0
- data/test/fixtures/geocodio_over_query_limit +4 -0
- data/test/fixtures/here_madison_square_garden +72 -0
- data/test/fixtures/here_no_results +8 -0
- data/test/fixtures/nominatim_over_limit +1 -0
- data/test/fixtures/smarty_streets_11211 +1 -0
- data/test/fixtures/smarty_streets_madison_square_garden +47 -0
- data/test/fixtures/smarty_streets_no_results +1 -0
- data/test/fixtures/yandex_canada_rue_dupuis_14 +446 -0
- data/test/fixtures/yandex_new_york +1 -0
- data/test/integration/http_client_test.rb +25 -0
- data/test/mongoid_test_helper.rb +2 -2
- data/test/test_helper.rb +98 -30
- data/test/{active_record_test.rb → unit/active_record_test.rb} +4 -3
- data/test/{cache_test.rb → unit/cache_test.rb} +3 -1
- data/test/{calculations_test.rb → unit/calculations_test.rb} +22 -13
- data/test/{configuration_test.rb → unit/configuration_test.rb} +4 -27
- data/test/{error_handling_test.rb → unit/error_handling_test.rb} +10 -9
- data/test/{geocoder_test.rb → unit/geocoder_test.rb} +26 -7
- data/test/{https_test.rb → unit/https_test.rb} +4 -3
- data/test/unit/ip_address_test.rb +24 -0
- data/test/{lookup_test.rb → unit/lookup_test.rb} +33 -20
- data/test/unit/lookups/bing_test.rb +68 -0
- data/test/unit/lookups/dstk_test.rb +26 -0
- data/test/unit/lookups/esri_test.rb +48 -0
- data/test/unit/lookups/freegeoip_test.rb +27 -0
- data/test/unit/lookups/geocoder_ca_test.rb +17 -0
- data/test/unit/lookups/geocodio_test.rb +55 -0
- data/test/unit/lookups/google_premier_test.rb +22 -0
- data/test/unit/lookups/google_test.rb +84 -0
- data/test/unit/lookups/mapquest_test.rb +60 -0
- data/test/unit/lookups/maxmind_local_test.rb +28 -0
- data/test/unit/lookups/maxmind_test.rb +63 -0
- data/test/unit/lookups/nominatim_test.rb +31 -0
- data/test/unit/lookups/smarty_streets_test.rb +71 -0
- data/test/unit/lookups/yahoo_test.rb +35 -0
- data/test/{method_aliases_test.rb → unit/method_aliases_test.rb} +5 -4
- data/test/unit/model_test.rb +38 -0
- data/test/{mongoid_test.rb → unit/mongoid_test.rb} +10 -9
- data/test/unit/near_test.rb +87 -0
- data/test/{oauth_util_test.rb → unit/oauth_util_test.rb} +3 -2
- data/test/{proxy_test.rb → unit/proxy_test.rb} +2 -1
- data/test/{query_test.rb → unit/query_test.rb} +7 -8
- data/test/unit/rake_task_test.rb +21 -0
- data/test/{request_test.rb → unit/request_test.rb} +8 -2
- data/test/{result_test.rb → unit/result_test.rb} +29 -1
- data/test/{test_mode_test.rb → unit/test_mode_test.rb} +12 -1
- metadata +80 -27
- data/test/custom_block_test.rb +0 -32
- data/test/integration/smoke_test.rb +0 -26
- data/test/near_test.rb +0 -61
- data/test/services_test.rb +0 -393
@@ -0,0 +1,17 @@
|
|
1
|
+
class GeocoderMaxmindGeoliteCountry < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :maxmind_geolite_country, id: false do |t|
|
4
|
+
t.column :start_ip, :string
|
5
|
+
t.column :end_ip, :string
|
6
|
+
t.column :start_ip_num, :bigint, null: false
|
7
|
+
t.column :end_ip_num, :bigint, null: false
|
8
|
+
t.column :country_code, :string, null: false
|
9
|
+
t.column :country, :string, null: false
|
10
|
+
end
|
11
|
+
add_index :maxmind_geolite_country, :start_ip_num, unique: true
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :maxmind_geolite_country
|
16
|
+
end
|
17
|
+
end
|
data/lib/geocoder.rb
CHANGED
@@ -5,17 +5,17 @@ require "geocoder/exceptions"
|
|
5
5
|
require "geocoder/cache"
|
6
6
|
require "geocoder/request"
|
7
7
|
require "geocoder/lookup"
|
8
|
+
require "geocoder/ip_address"
|
8
9
|
require "geocoder/models/active_record" if defined?(::ActiveRecord)
|
9
10
|
require "geocoder/models/mongoid" if defined?(::Mongoid)
|
10
11
|
require "geocoder/models/mongo_mapper" if defined?(::MongoMapper)
|
11
12
|
|
12
13
|
module Geocoder
|
13
|
-
extend self
|
14
14
|
|
15
15
|
##
|
16
16
|
# Search for information about an address or a set of coordinates.
|
17
17
|
#
|
18
|
-
def search(query, options = {})
|
18
|
+
def self.search(query, options = {})
|
19
19
|
query = Geocoder::Query.new(query, options) unless query.is_a?(Geocoder::Query)
|
20
20
|
query.blank? ? [] : query.execute
|
21
21
|
end
|
@@ -23,7 +23,7 @@ module Geocoder
|
|
23
23
|
##
|
24
24
|
# Look up the coordinates of the given street or IP address.
|
25
25
|
#
|
26
|
-
def coordinates(address, options = {})
|
26
|
+
def self.coordinates(address, options = {})
|
27
27
|
if (results = search(address, options)).size > 0
|
28
28
|
results.first.coordinates
|
29
29
|
end
|
@@ -33,19 +33,11 @@ module Geocoder
|
|
33
33
|
# Look up the address of the given coordinates ([lat,lon])
|
34
34
|
# or IP address (string).
|
35
35
|
#
|
36
|
-
def address(query, options = {})
|
36
|
+
def self.address(query, options = {})
|
37
37
|
if (results = search(query, options)).size > 0
|
38
38
|
results.first.address
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
42
|
-
##
|
43
|
-
# The working Cache object, or +nil+ if none configured.
|
44
|
-
#
|
45
|
-
def cache
|
46
|
-
warn "WARNING: Calling Geocoder.cache is DEPRECATED. The #cache method now belongs to the Geocoder::Lookup object."
|
47
|
-
Geocoder::Lookup.get(Geocoder.config.lookup).cache
|
48
|
-
end
|
49
41
|
end
|
50
42
|
|
51
43
|
# load Railtie if Rails exists
|
data/lib/geocoder/cache.rb
CHANGED
@@ -49,7 +49,8 @@ module Geocoder
|
|
49
49
|
|
50
50
|
private # ----------------------------------------------------------------
|
51
51
|
|
52
|
-
|
52
|
+
def prefix; @prefix; end
|
53
|
+
def store; @store; end
|
53
54
|
|
54
55
|
##
|
55
56
|
# Cache key for a given URL.
|
@@ -63,7 +64,7 @@ module Geocoder
|
|
63
64
|
# that have non-nil values.
|
64
65
|
#
|
65
66
|
def keys
|
66
|
-
store.keys.select{ |k| k.match
|
67
|
+
store.keys.select{ |k| k.match(/^#{prefix}/) and interpret(store[k]) }
|
67
68
|
end
|
68
69
|
|
69
70
|
##
|
@@ -26,6 +26,11 @@ module Geocoder
|
|
26
26
|
#
|
27
27
|
KM_IN_NM = 0.539957
|
28
28
|
|
29
|
+
##
|
30
|
+
# Conversion factor: multiply by radians to get degrees.
|
31
|
+
#
|
32
|
+
DEGREES_PER_RADIAN = 57.2957795
|
33
|
+
|
29
34
|
# Not a number constant
|
30
35
|
NAN = defined?(::Float::NAN) ? ::Float::NAN : 0 / 0.0
|
31
36
|
|
@@ -254,6 +259,40 @@ module Geocoder
|
|
254
259
|
[center[0] + delta_lat, center[1] + delta_long]
|
255
260
|
end
|
256
261
|
|
262
|
+
##
|
263
|
+
# Given a start point, distance, and heading (in degrees), provides
|
264
|
+
# an endpoint.
|
265
|
+
# The starting point is given in the same way that points are given to all
|
266
|
+
# Geocoder methods that accept points as arguments. It can be:
|
267
|
+
#
|
268
|
+
# * an array of coordinates ([lat,lon])
|
269
|
+
# * a geocodable address (string)
|
270
|
+
# * a geocoded object (one which implements a +to_coordinates+ method
|
271
|
+
# which returns a [lat,lon] array
|
272
|
+
#
|
273
|
+
def endpoint(start, heading, distance, options = {})
|
274
|
+
options[:units] ||= Geocoder.config.units
|
275
|
+
radius = earth_radius(options[:units])
|
276
|
+
|
277
|
+
start = extract_coordinates(start)
|
278
|
+
|
279
|
+
# convert degrees to radians
|
280
|
+
start = to_radians(start)
|
281
|
+
|
282
|
+
lat = start[0]
|
283
|
+
lon = start[1]
|
284
|
+
heading = to_radians(heading)
|
285
|
+
distance = distance.to_f
|
286
|
+
|
287
|
+
end_lat = Math.asin(Math.sin(lat)*Math.cos(distance/radius) +
|
288
|
+
Math.cos(lat)*Math.sin(distance/radius)*Math.cos(heading))
|
289
|
+
|
290
|
+
end_lon = lon+Math.atan2(Math.sin(heading)*Math.sin(distance/radius)*Math.cos(lat),
|
291
|
+
Math.cos(distance/radius)-Math.sin(lat)*Math.sin(end_lat))
|
292
|
+
|
293
|
+
to_degrees [end_lat, end_lon]
|
294
|
+
end
|
295
|
+
|
257
296
|
##
|
258
297
|
# Convert degrees to radians.
|
259
298
|
# If an array (or multiple arguments) is passed,
|
@@ -14,14 +14,8 @@ module Geocoder
|
|
14
14
|
# )
|
15
15
|
#
|
16
16
|
def self.configure(options = nil, &block)
|
17
|
-
if
|
18
|
-
warn "WARNING: Passing a block to Geocoder.configure is DEPRECATED. Please pass a hash instead (eg: Geocoder.configure(:units => ..., :api_key => ...))."
|
19
|
-
block.call(Configuration.instance)
|
20
|
-
elsif !options.nil?
|
17
|
+
if !options.nil?
|
21
18
|
Configuration.instance.configure(options)
|
22
|
-
else
|
23
|
-
warn "WARNING: Use of Geocoder.configure to read or write single config options is DEPRECATED. To write to the config please pass a hash (eg: Geocoder.configure(:units => ...)). To read config options please use the Geocoder.config object (eg: Geocoder.config.units)."
|
24
|
-
Configuration.instance
|
25
19
|
end
|
26
20
|
end
|
27
21
|
|
data/lib/geocoder/lookup.rb
CHANGED
@@ -33,7 +33,11 @@ module Geocoder
|
|
33
33
|
:nominatim,
|
34
34
|
:mapquest,
|
35
35
|
:ovi,
|
36
|
+
:here,
|
36
37
|
:baidu,
|
38
|
+
:cloudmade,
|
39
|
+
:geocodio,
|
40
|
+
:smarty_streets,
|
37
41
|
:test
|
38
42
|
]
|
39
43
|
end
|
@@ -42,7 +46,12 @@ module Geocoder
|
|
42
46
|
# All IP address lookup services, default first.
|
43
47
|
#
|
44
48
|
def ip_services
|
45
|
-
[
|
49
|
+
[
|
50
|
+
:freegeoip,
|
51
|
+
:maxmind,
|
52
|
+
:maxmind_local,
|
53
|
+
:baidu_ip
|
54
|
+
]
|
46
55
|
end
|
47
56
|
|
48
57
|
##
|
@@ -20,22 +20,23 @@ module Geocoder::Lookup
|
|
20
20
|
|
21
21
|
def results(query, reverse = false)
|
22
22
|
return [] unless doc = fetch_data(query)
|
23
|
-
case doc['status']
|
23
|
+
case doc['status']
|
24
|
+
when 0
|
24
25
|
return [doc['result']] unless doc['result'].blank?
|
25
26
|
when 1, 3, 4
|
26
|
-
raise_error(Geocoder::Error,
|
27
|
+
raise_error(Geocoder::Error, "server error.") ||
|
27
28
|
warn("Baidu Geocoding API error: server error.")
|
28
29
|
when 2
|
29
|
-
raise_error(Geocoder::InvalidRequest,
|
30
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
30
31
|
warn("Baidu Geocoding API error: invalid request.")
|
31
32
|
when 5
|
32
|
-
raise_error(Geocoder::InvalidApiKey,
|
33
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
33
34
|
warn("Baidu Geocoding API error: invalid api key.")
|
34
35
|
when 101, 102, 200..299
|
35
|
-
raise_error(Geocoder::RequestDenied) ||
|
36
|
+
raise_error(Geocoder::RequestDenied, "request denied") ||
|
36
37
|
warn("Baidu Geocoding API error: request denied.")
|
37
38
|
when 300..399
|
38
|
-
raise_error(Geocoder::OverQueryLimitError) ||
|
39
|
+
raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
|
39
40
|
warn("Baidu Geocoding API error: over query limit.")
|
40
41
|
end
|
41
42
|
return []
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/baidu_ip'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class BaiduIp < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Baidu IP"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
["key"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def query_url(query)
|
16
|
+
"http://api.map.baidu.com/location/ip?" + url_query_string(query)
|
17
|
+
end
|
18
|
+
|
19
|
+
private # ---------------------------------------------------------------
|
20
|
+
|
21
|
+
def results(query, reverse = false)
|
22
|
+
return [] unless doc = fetch_data(query)
|
23
|
+
case doc['status']
|
24
|
+
when 0
|
25
|
+
return [doc['content']] unless doc['content'].blank?
|
26
|
+
when 1, 3, 4
|
27
|
+
raise_error(Geocoder::Error, "server error.") ||
|
28
|
+
warn("Baidu IP Geocoding API error: server error.")
|
29
|
+
when 2
|
30
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
31
|
+
warn("Baidu IP Geocoding API error: invalid request.")
|
32
|
+
when 5
|
33
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
|
34
|
+
warn("Baidu IP Geocoding API error: invalid api key.")
|
35
|
+
when 101, 102, 200..299
|
36
|
+
raise_error(Geocoder::RequestDenied, "request denied.") ||
|
37
|
+
warn("Baidu IP Geocoding API error: request denied.")
|
38
|
+
when 300..399
|
39
|
+
raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
|
40
|
+
warn("Baidu IP Geocoding API error: over query limit.")
|
41
|
+
end
|
42
|
+
return []
|
43
|
+
end
|
44
|
+
|
45
|
+
def query_url_params(query)
|
46
|
+
{
|
47
|
+
:ip => query.sanitized_text,
|
48
|
+
:ak => configuration.api_key,
|
49
|
+
:coor => "bd09ll"
|
50
|
+
}.merge(super)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -15,6 +15,9 @@ module Geocoder
|
|
15
15
|
module Lookup
|
16
16
|
|
17
17
|
class Base
|
18
|
+
def initialize
|
19
|
+
@cache = nil
|
20
|
+
end
|
18
21
|
|
19
22
|
##
|
20
23
|
# Human-readable name of the geocoding API.
|
@@ -211,7 +214,21 @@ module Geocoder
|
|
211
214
|
else
|
212
215
|
check_api_key_configuration!(query)
|
213
216
|
response = make_api_request(query)
|
217
|
+
check_response_for_errors!(response)
|
214
218
|
body = response.body
|
219
|
+
|
220
|
+
# apply the charset from the Content-Type header, if possible
|
221
|
+
ct = response['content-type']
|
222
|
+
|
223
|
+
if ct && ct['charset']
|
224
|
+
charset = ct.split(';').select do |s|
|
225
|
+
s['charset']
|
226
|
+
end.first.to_s.split('=')
|
227
|
+
if charset.length == 2
|
228
|
+
body.force_encoding(charset.last) rescue ArgumentError
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
215
232
|
if cache and valid_response?(response)
|
216
233
|
cache[key] = body
|
217
234
|
end
|
@@ -220,6 +237,19 @@ module Geocoder
|
|
220
237
|
body
|
221
238
|
end
|
222
239
|
|
240
|
+
def check_response_for_errors!(response)
|
241
|
+
if response.code.to_i == 400
|
242
|
+
raise_error(Geocoder::InvalidRequest) ||
|
243
|
+
warn("Geocoding API error: 400 Bad Request")
|
244
|
+
elsif response.code.to_i == 401
|
245
|
+
raise_error(Geocoder::RequestDenied) ||
|
246
|
+
warn("Geocoding API error: 401 Unauthorized")
|
247
|
+
elsif response.code.to_i == 402
|
248
|
+
raise_error(Geocoder::OverQueryLimitError) ||
|
249
|
+
warn("Geocoding API error: 402 Payment Required")
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
223
253
|
##
|
224
254
|
# Make an HTTP(S) request to a geocoding API and
|
225
255
|
# return the response object.
|
@@ -227,15 +257,13 @@ module Geocoder
|
|
227
257
|
def make_api_request(query)
|
228
258
|
timeout(configuration.timeout) do
|
229
259
|
uri = URI.parse(query_url(query))
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
req.basic_auth(uri.user, uri.password) if uri.user and uri.password
|
238
|
-
client.request(req)
|
260
|
+
args = [uri.host, uri.port]
|
261
|
+
args = args.push(uri.user, uri.password) unless uri.user.nil? or uri.password.nil?
|
262
|
+
opts = {}
|
263
|
+
opts[:use_ssl] = true if configuration.use_https
|
264
|
+
|
265
|
+
http_client.start(*args, opts) do |client|
|
266
|
+
client.get(uri.request_uri, configuration.http_headers)
|
239
267
|
end
|
240
268
|
end
|
241
269
|
end
|
@@ -17,13 +17,19 @@ module Geocoder::Lookup
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def query_url(query)
|
20
|
-
|
21
|
-
(query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?") +
|
22
|
-
url_query_string(query)
|
20
|
+
base_url(query) + url_query_string(query)
|
23
21
|
end
|
24
22
|
|
25
23
|
private # ---------------------------------------------------------------
|
26
24
|
|
25
|
+
def base_url(query)
|
26
|
+
url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations"
|
27
|
+
if !query.reverse_geocode? and r = query.options[:region]
|
28
|
+
url << "/#{r}"
|
29
|
+
end
|
30
|
+
url + "/" + URI.escape(query.sanitized_text.strip) + "?"
|
31
|
+
end
|
32
|
+
|
27
33
|
def results(query)
|
28
34
|
return [] unless doc = fetch_data(query)
|
29
35
|
|
@@ -39,8 +45,7 @@ module Geocoder::Lookup
|
|
39
45
|
|
40
46
|
def query_url_params(query)
|
41
47
|
{
|
42
|
-
:
|
43
|
-
:query => query.reverse_geocode? ? nil : query.sanitized_text
|
48
|
+
key: configuration.api_key
|
44
49
|
}.merge(super)
|
45
50
|
end
|
46
51
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/cloudmade'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Cloudmade < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Cloudmade"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_url(query)
|
12
|
+
"http://geocoding.cloudmade.com/#{configuration.api_key}/geocoding/v2/find.js?#{url_query_string(query)}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def required_api_key_parts
|
16
|
+
["key"]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def results(query)
|
22
|
+
data = fetch_data(query)
|
23
|
+
(data && data['features']) || []
|
24
|
+
end
|
25
|
+
|
26
|
+
def query_url_params(query)
|
27
|
+
{
|
28
|
+
:query => query.sanitized_text,
|
29
|
+
:return_location => true,
|
30
|
+
:return_geometry => false
|
31
|
+
}.merge(super)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -9,7 +9,7 @@ module Geocoder::Lookup
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def query_url(query)
|
12
|
-
"#{protocol}
|
12
|
+
"#{protocol}://#{host}/json/#{query.sanitized_text}"
|
13
13
|
end
|
14
14
|
|
15
15
|
private # ---------------------------------------------------------------
|
@@ -39,5 +39,9 @@ module Geocoder::Lookup
|
|
39
39
|
"country_code" => "RD"
|
40
40
|
}
|
41
41
|
end
|
42
|
+
|
43
|
+
def host
|
44
|
+
configuration[:host] || "freegeoip.net"
|
45
|
+
end
|
42
46
|
end
|
43
47
|
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 query_url(query)
|
12
|
+
path = query.reverse_geocode? ? "reverse" : "geocode"
|
13
|
+
"#{protocol}://api.geocod.io/v1/#{path}?#{url_query_string(query)}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def results(query)
|
17
|
+
return [] unless doc = fetch_data(query)
|
18
|
+
return doc["results"] if doc['error'].nil?
|
19
|
+
|
20
|
+
if doc['error'] == 'Invalid API key'
|
21
|
+
raise_error(Geocoder::InvalidApiKey) ||
|
22
|
+
warn("Geocodio service error: invalid API key.")
|
23
|
+
elsif doc['error'].match(/You have reached your daily maximum/)
|
24
|
+
raise_error(Geocoder::OverQueryLimitError, doc['error']) ||
|
25
|
+
warn("Geocodio service error: #{doc['error']}.")
|
26
|
+
else
|
27
|
+
raise_error(Geocoder::InvalidRequest, doc['error']) ||
|
28
|
+
warn("Geocodio service error: #{doc['error']}.")
|
29
|
+
end
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
|
33
|
+
private # ---------------------------------------------------------------
|
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
|