geocoder 1.1.3 → 1.1.4
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/CHANGELOG.rdoc +12 -0
- data/README.md +580 -0
- data/examples/autoexpire_cache.rb +30 -0
- data/lib/geocoder.rb +9 -85
- data/lib/geocoder/calculations.rb +1 -1
- data/lib/geocoder/cli.rb +9 -10
- data/lib/geocoder/configuration.rb +3 -1
- data/lib/geocoder/lookup.rb +81 -0
- data/lib/geocoder/lookups/base.rb +20 -32
- data/lib/geocoder/lookups/bing.rb +12 -8
- data/lib/geocoder/lookups/freegeoip.rb +5 -5
- data/lib/geocoder/lookups/geocoder_ca.rb +13 -9
- data/lib/geocoder/lookups/google.rb +19 -7
- data/lib/geocoder/lookups/google_premier.rb +8 -7
- data/lib/geocoder/lookups/mapquest.rb +5 -23
- data/lib/geocoder/lookups/nominatim.rb +16 -13
- data/lib/geocoder/lookups/test.rb +8 -6
- data/lib/geocoder/lookups/yahoo.rb +49 -10
- data/lib/geocoder/lookups/yandex.rb +15 -8
- data/lib/geocoder/models/mongoid.rb +0 -1
- data/lib/geocoder/query.rb +88 -0
- data/lib/geocoder/results/mapquest.rb +2 -61
- data/lib/geocoder/results/nominatim.rb +24 -3
- data/lib/geocoder/sql.rb +104 -0
- data/lib/geocoder/stores/active_record.rb +68 -140
- data/lib/geocoder/stores/mongo_base.rb +2 -2
- data/lib/geocoder/version.rb +1 -1
- data/test/active_record_test.rb +15 -0
- data/test/calculations_test.rb +7 -0
- data/test/error_handling_test.rb +7 -7
- data/test/fixtures/yahoo_madison_square_garden.json +49 -43
- data/test/fixtures/yahoo_v1_madison_square_garden.json +46 -0
- data/test/fixtures/yahoo_v1_no_results.json +10 -0
- data/test/https_test.rb +2 -2
- data/test/integration/smoke_test.rb +6 -4
- data/test/lookup_test.rb +13 -6
- data/test/query_test.rb +34 -0
- data/test/result_test.rb +1 -1
- data/test/services_test.rb +48 -7
- data/test/test_helper.rb +64 -49
- data/test/test_mode_test.rb +0 -1
- metadata +13 -7
- data/README.rdoc +0 -552
- data/test/fixtures/yahoo_garbage.json +0 -50
- data/test/input_handling_test.rb +0 -43
@@ -59,7 +59,7 @@ module Geocoder::Store
|
|
59
59
|
do_lookup(false) do |o,rs|
|
60
60
|
if r = rs.first
|
61
61
|
unless r.coordinates.nil?
|
62
|
-
o.
|
62
|
+
o.__send__ "#{self.class.geocoder_options[:coordinates]}=", r.coordinates.reverse
|
63
63
|
end
|
64
64
|
r.coordinates
|
65
65
|
end
|
@@ -74,7 +74,7 @@ module Geocoder::Store
|
|
74
74
|
do_lookup(true) do |o,rs|
|
75
75
|
if r = rs.first
|
76
76
|
unless r.address.nil?
|
77
|
-
o.
|
77
|
+
o.__send__ "#{self.class.geocoder_options[:fetched_address]}=", r.address
|
78
78
|
end
|
79
79
|
r.address
|
80
80
|
end
|
data/lib/geocoder/version.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class ActiveRecordTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_exclude_condition_when_model_has_a_custom_primary_key
|
7
|
+
venue = VenuePlus.new(*venue_params(:msg))
|
8
|
+
|
9
|
+
# just call private method directly so we don't have to stub .near scope
|
10
|
+
conditions = venue.class.send(:add_exclude_condition, ["fake_condition"], venue)
|
11
|
+
|
12
|
+
assert_match( /#{VenuePlus.primary_key}/, conditions.join)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/test/calculations_test.rb
CHANGED
@@ -185,4 +185,11 @@ class CalculationsTest < Test::Unit::TestCase
|
|
185
185
|
assert !Geocoder::Calculations.coordinates_present?(Geocoder::Calculations::NAN)
|
186
186
|
assert !Geocoder::Calculations.coordinates_present?(3.23, nil)
|
187
187
|
end
|
188
|
+
|
189
|
+
def test_extract_coordinates
|
190
|
+
coords = [-23,47]
|
191
|
+
l = Landmark.new("Madagascar", coords[0], coords[1])
|
192
|
+
assert_equal coords, Geocoder::Calculations.extract_coordinates(l)
|
193
|
+
assert_equal coords, Geocoder::Calculations.extract_coordinates(coords)
|
194
|
+
end
|
188
195
|
end
|
data/test/error_handling_test.rb
CHANGED
@@ -10,7 +10,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
|
|
10
10
|
def test_does_not_choke_on_timeout
|
11
11
|
# keep test output clean: suppress timeout warning
|
12
12
|
orig = $VERBOSE; $VERBOSE = nil
|
13
|
-
|
13
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
14
14
|
Geocoder::Configuration.lookup = l
|
15
15
|
assert_nothing_raised { Geocoder.search("timeout") }
|
16
16
|
end
|
@@ -19,20 +19,20 @@ class ErrorHandlingTest < Test::Unit::TestCase
|
|
19
19
|
|
20
20
|
def test_always_raise_timeout_error
|
21
21
|
Geocoder::Configuration.always_raise = [TimeoutError]
|
22
|
-
|
23
|
-
lookup = Geocoder.
|
22
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
23
|
+
lookup = Geocoder::Lookup.get(l)
|
24
24
|
assert_raises TimeoutError do
|
25
|
-
lookup.send(:results, "timeout")
|
25
|
+
lookup.send(:results, Geocoder::Query.new("timeout"))
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_always_raise_socket_error
|
31
31
|
Geocoder::Configuration.always_raise = [SocketError]
|
32
|
-
|
33
|
-
lookup = Geocoder.
|
32
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
33
|
+
lookup = Geocoder::Lookup.get(l)
|
34
34
|
assert_raises SocketError do
|
35
|
-
lookup.send(:results, "socket_error")
|
35
|
+
lookup.send(:results, Geocoder::Query.new("socket_error"))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -1,46 +1,52 @@
|
|
1
1
|
{
|
2
|
-
"
|
3
|
-
|
4
|
-
"
|
5
|
-
"
|
6
|
-
"
|
7
|
-
"
|
8
|
-
"
|
9
|
-
"
|
10
|
-
|
11
|
-
|
12
|
-
"
|
13
|
-
"
|
14
|
-
"
|
15
|
-
"
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
35
|
-
"
|
36
|
-
"
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
44
|
-
|
2
|
+
"@lang": "en-US",
|
3
|
+
"ResultSet": {
|
4
|
+
"@version": "2.0",
|
5
|
+
"@lang": "en-US",
|
6
|
+
"Error": "0",
|
7
|
+
"ErrorMessage": "No error",
|
8
|
+
"Locale": "en-US",
|
9
|
+
"Found": "1",
|
10
|
+
"Quality": "90",
|
11
|
+
"Result": {
|
12
|
+
"quality": "90",
|
13
|
+
"latitude": "40.750381",
|
14
|
+
"longitude": "-73.993988",
|
15
|
+
"offsetlat": "40.750381",
|
16
|
+
"offsetlon": "-73.993988",
|
17
|
+
"radius": "100",
|
18
|
+
"boundingbox": {
|
19
|
+
"north": "40.750832",
|
20
|
+
"south": "40.749931",
|
21
|
+
"east": "-73.993393",
|
22
|
+
"west": "-73.994591"
|
23
|
+
},
|
24
|
+
"name": "Madison Square Garden",
|
25
|
+
"line1": "Madison Square Garden",
|
26
|
+
"line2": "New York, NY 10001",
|
27
|
+
"line3": "",
|
28
|
+
"line4": "United States",
|
29
|
+
"cross": "",
|
30
|
+
"house": "",
|
31
|
+
"street": "",
|
32
|
+
"xstreet": "",
|
33
|
+
"unittype": "",
|
34
|
+
"unit": "",
|
35
|
+
"postal": "10001",
|
36
|
+
"neighborhood": "Garment District|Midtown|Midtown West|Manhattan",
|
37
|
+
"city": "New York",
|
38
|
+
"county": "New York County",
|
39
|
+
"state": "New York",
|
40
|
+
"country": "United States",
|
41
|
+
"countrycode": "US",
|
42
|
+
"statecode": "NY",
|
43
|
+
"countycode": "",
|
44
|
+
"timezone": "America/New_York",
|
45
|
+
"areacode": "212",
|
46
|
+
"uzip": "10001",
|
47
|
+
"hash": "",
|
48
|
+
"woeid": "23617041",
|
49
|
+
"woetype": "20"
|
50
|
+
}
|
45
51
|
}
|
46
52
|
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"ResultSet":{
|
3
|
+
"version":"1.0",
|
4
|
+
"Error":0,
|
5
|
+
"ErrorMessage":"No error",
|
6
|
+
"Locale":"us_US",
|
7
|
+
"Quality":90,
|
8
|
+
"Found":1,
|
9
|
+
"Results":[{
|
10
|
+
"quality":90,
|
11
|
+
"latitude":"40.750381",
|
12
|
+
"longitude":"-73.993988",
|
13
|
+
"offsetlat":"40.750381",
|
14
|
+
"offsetlon":"-73.993988",
|
15
|
+
"radius":100,
|
16
|
+
"name":"Madison Square Garden",
|
17
|
+
"line1":"Madison Square Garden",
|
18
|
+
"line2":"New York, NY 10001",
|
19
|
+
"line3":"",
|
20
|
+
"line4":"United States",
|
21
|
+
"house":"",
|
22
|
+
"street":"",
|
23
|
+
"xstreet":"",
|
24
|
+
"unittype":"",
|
25
|
+
"unit":"",
|
26
|
+
"postal":"10001",
|
27
|
+
"neighborhood":"",
|
28
|
+
"city":"New York",
|
29
|
+
"county":"New York County",
|
30
|
+
"state":"New York",
|
31
|
+
"country":"United States",
|
32
|
+
"countrycode":"US",
|
33
|
+
"statecode":"NY",
|
34
|
+
"countycode":"",
|
35
|
+
"uzip":"10001",
|
36
|
+
"hash":"",
|
37
|
+
"woeid":23617041,
|
38
|
+
"woetype":20,
|
39
|
+
"cross":"",
|
40
|
+
"timezone":"America/New_York",
|
41
|
+
"neighborhood":"Garment District|Midtown|Midtown West|Manhattan",
|
42
|
+
"areacode":"212",
|
43
|
+
"boundingbox":{"north":"40.750832","south":"40.749931","east":"-73.993393","west":"-73.994591"}
|
44
|
+
}]
|
45
|
+
}
|
46
|
+
}
|
data/test/https_test.rb
CHANGED
@@ -6,11 +6,11 @@ class HttpsTest < Test::Unit::TestCase
|
|
6
6
|
def test_uses_https_for_secure_query
|
7
7
|
Geocoder::Configuration.use_https = true
|
8
8
|
g = Geocoder::Lookup::Google.new
|
9
|
-
assert_match /^https:/, g.send(:query_url,
|
9
|
+
assert_match /^https:/, g.send(:query_url, Geocoder::Query.new("test"))
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_uses_http_by_default
|
13
13
|
g = Geocoder::Lookup::Google.new
|
14
|
-
assert_match /^http:/, g.send(:query_url,
|
14
|
+
assert_match /^http:/, g.send(:query_url, Geocoder::Query.new("test"))
|
15
15
|
end
|
16
16
|
end
|
@@ -8,15 +8,17 @@ class SmokeTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
def test_simple_zip_code_search
|
10
10
|
result = Geocoder.search "27701"
|
11
|
-
|
12
|
-
assert_equal "
|
11
|
+
assert_not_nil (r = result.first)
|
12
|
+
assert_equal "Durham", r.city
|
13
|
+
assert_equal "North Carolina", r.state
|
13
14
|
end
|
14
15
|
|
15
16
|
def test_simple_zip_code_search_with_ssl
|
16
17
|
Geocoder::Configuration.use_https = true
|
17
18
|
result = Geocoder.search "27701"
|
18
|
-
|
19
|
-
assert_equal "
|
19
|
+
assert_not_nil (r = result.first)
|
20
|
+
assert_equal "Durham", r.city
|
21
|
+
assert_equal "North Carolina", r.state
|
20
22
|
ensure
|
21
23
|
Geocoder::Configuration.use_https = false
|
22
24
|
end
|
data/test/lookup_test.rb
CHANGED
@@ -4,13 +4,20 @@ require 'test_helper'
|
|
4
4
|
class LookupTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_search_returns_empty_array_when_no_results
|
7
|
-
|
8
|
-
lookup = Geocoder.
|
9
|
-
assert_equal [], lookup.send(:results, "no results"),
|
7
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
8
|
+
lookup = Geocoder::Lookup.get(l)
|
9
|
+
assert_equal [], lookup.send(:results, Geocoder::Query.new("no results")),
|
10
10
|
"Lookup #{l} does not return empty array when no results."
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_does_not_choke_on_nil_address
|
15
|
+
Geocoder::Lookup.all_services.each do |l|
|
16
|
+
Geocoder::Configuration.lookup = l
|
17
|
+
assert_nothing_raised { Venue.new("Venue", nil).geocode }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
14
21
|
def test_hash_to_query
|
15
22
|
g = Geocoder::Lookup::Google.new
|
16
23
|
assert_equal "a=1&b=2", g.send(:hash_to_query, {:a => 1, :b => 2})
|
@@ -19,19 +26,19 @@ class LookupTest < Test::Unit::TestCase
|
|
19
26
|
def test_google_api_key
|
20
27
|
Geocoder::Configuration.api_key = "MY_KEY"
|
21
28
|
g = Geocoder::Lookup::Google.new
|
22
|
-
assert_match "key=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
|
29
|
+
assert_match "key=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
|
23
30
|
end
|
24
31
|
|
25
32
|
def test_yahoo_app_id
|
26
33
|
Geocoder::Configuration.api_key = "MY_KEY"
|
27
34
|
g = Geocoder::Lookup::Yahoo.new
|
28
|
-
assert_match "appid=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
|
35
|
+
assert_match "appid=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
|
29
36
|
end
|
30
37
|
|
31
38
|
def test_geocoder_ca_showpostal
|
32
39
|
Geocoder::Configuration.api_key = "MY_KEY"
|
33
40
|
g = Geocoder::Lookup::GeocoderCa.new
|
34
|
-
assert_match "showpostal=1", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
|
41
|
+
assert_match "showpostal=1", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
|
35
42
|
end
|
36
43
|
|
37
44
|
end
|
data/test/query_test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class QueryTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_ip_address_detection
|
7
|
+
assert Geocoder::Query.new("232.65.123.94").ip_address?
|
8
|
+
assert Geocoder::Query.new("666.65.123.94").ip_address? # technically invalid
|
9
|
+
assert Geocoder::Query.new("::ffff:12.34.56.78").ip_address?
|
10
|
+
assert !Geocoder::Query.new("232.65.123.94.43").ip_address?
|
11
|
+
assert !Geocoder::Query.new("232.65.123").ip_address?
|
12
|
+
assert !Geocoder::Query.new("::ffff:123.456.789").ip_address?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_blank_query_detection
|
16
|
+
assert Geocoder::Query.new(nil).blank?
|
17
|
+
assert Geocoder::Query.new("").blank?
|
18
|
+
assert Geocoder::Query.new("\t ").blank?
|
19
|
+
assert !Geocoder::Query.new("a").blank?
|
20
|
+
assert !Geocoder::Query.new("Москва").blank? # no ASCII characters
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_coordinates_detection
|
24
|
+
assert Geocoder::Query.new("51.178844,5").coordinates?
|
25
|
+
assert Geocoder::Query.new("51.178844, -1.826189").coordinates?
|
26
|
+
assert !Geocoder::Query.new("232.65.123").coordinates?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_loopback_ip_address
|
30
|
+
assert Geocoder::Query.new("0.0.0.0").loopback_ip_address?
|
31
|
+
assert Geocoder::Query.new("127.0.0.1").loopback_ip_address?
|
32
|
+
assert !Geocoder::Query.new("232.65.123.234").loopback_ip_address?
|
33
|
+
end
|
34
|
+
end
|
data/test/result_test.rb
CHANGED
@@ -4,7 +4,7 @@ require 'test_helper'
|
|
4
4
|
class ResultTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_result_has_required_attributes
|
7
|
-
|
7
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
8
8
|
Geocoder::Configuration.lookup = l
|
9
9
|
result = Geocoder.search([45.423733, -75.676333]).first
|
10
10
|
assert_result_has_required_attributes(result)
|
data/test/services_test.rb
CHANGED
@@ -4,6 +4,18 @@ require 'test_helper'
|
|
4
4
|
class ServicesTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
|
7
|
+
def test_query_url_contains_values_in_params_hash
|
8
|
+
Geocoder::Lookup.all_services_except_test.each do |l|
|
9
|
+
next if l == :google_premier # TODO: need to set keys to test
|
10
|
+
next if l == :freegeoip # does not use query string
|
11
|
+
url = Geocoder::Lookup.get(l).send(:query_url, Geocoder::Query.new(
|
12
|
+
"test", :params => {:one_in_the_hand => "two in the bush"}
|
13
|
+
))
|
14
|
+
assert_match /one_in_the_hand=two\+in\+the\+bush/, url,
|
15
|
+
"Lookup #{l} does not appear to support arbitrary params in URL"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
7
19
|
# --- Google ---
|
8
20
|
|
9
21
|
def test_google_result_components
|
@@ -28,6 +40,14 @@ class ServicesTest < Test::Unit::TestCase
|
|
28
40
|
result.precision
|
29
41
|
end
|
30
42
|
|
43
|
+
def test_google_query_url_contains_bounds
|
44
|
+
lookup = Geocoder::Lookup::Google.new
|
45
|
+
url = lookup.send(:query_url, Geocoder::Query.new(
|
46
|
+
"Some Intersection",
|
47
|
+
:bounds => [[40.0, -120.0], [39.0, -121.0]]
|
48
|
+
))
|
49
|
+
assert_match /bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url
|
50
|
+
end
|
31
51
|
|
32
52
|
# --- Google Premier ---
|
33
53
|
|
@@ -41,23 +61,44 @@ class ServicesTest < Test::Unit::TestCase
|
|
41
61
|
def test_google_premier_query_url
|
42
62
|
Geocoder::Configuration.api_key = ["deadbeef", "gme-test", "test-dev"]
|
43
63
|
assert_equal "http://maps.googleapis.com/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&channel=test-dev&client=gme-test&language=en&sensor=false&signature=doJvJqX7YJzgV9rJ0DnVkTGZqTg=",
|
44
|
-
Geocoder::Lookup::GooglePremier.new.send(:query_url, "Madison Square Garden, New York, NY"
|
64
|
+
Geocoder::Lookup::GooglePremier.new.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY"))
|
45
65
|
end
|
46
66
|
|
47
67
|
|
48
68
|
# --- Yahoo ---
|
49
69
|
|
50
|
-
def
|
70
|
+
def test_yahoo_v1_no_results
|
51
71
|
Geocoder::Configuration.lookup = :yahoo
|
52
|
-
|
72
|
+
assert_equal [], Geocoder.search("no results v1")
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_yahoo_v1_result_components
|
76
|
+
Geocoder::Configuration.lookup = :yahoo
|
77
|
+
result = Geocoder.search("madison square garden v1").first
|
53
78
|
assert_equal "10001", result.postal_code
|
54
79
|
end
|
55
80
|
|
56
|
-
def
|
81
|
+
def test_yahoo_v1_address_formatting
|
57
82
|
Geocoder::Configuration.lookup = :yahoo
|
58
|
-
result = Geocoder.search("
|
59
|
-
assert_equal "Madison Square Garden, New York, NY 10001, United States",
|
60
|
-
|
83
|
+
result = Geocoder.search("madison square garden v1").first
|
84
|
+
assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_yahoo_v2_no_results
|
88
|
+
Geocoder::Configuration.lookup = :yahoo
|
89
|
+
assert_equal [], Geocoder.search("no results")
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_yahoo_v2_result_components
|
93
|
+
Geocoder::Configuration.lookup = :yahoo
|
94
|
+
result = Geocoder.search("madison square garden v2").first
|
95
|
+
assert_equal "10001", result.postal_code
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_yahoo_v2_address_formatting
|
99
|
+
Geocoder::Configuration.lookup = :yahoo
|
100
|
+
result = Geocoder.search("madison square garden v2").first
|
101
|
+
assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
|
61
102
|
end
|
62
103
|
|
63
104
|
|