graticule 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +11 -0
- data/Manifest.txt +26 -11
- data/README.txt +1 -1
- data/bin/geocode +1 -1
- data/lib/graticule.rb +10 -8
- data/lib/graticule/cli.rb +1 -0
- data/lib/graticule/geocoder.rb +1 -12
- data/lib/graticule/geocoder/bogus.rb +15 -0
- data/lib/graticule/geocoder/geocoder_ca.rb +52 -0
- data/lib/graticule/geocoder/geocoder_us.rb +47 -0
- data/lib/graticule/geocoder/google.rb +106 -0
- data/lib/graticule/geocoder/host_ip.rb +50 -0
- data/lib/graticule/geocoder/local_search_maps.rb +45 -0
- data/lib/graticule/geocoder/meta_carta.rb +38 -0
- data/lib/graticule/geocoder/postcode_anywhere.rb +63 -0
- data/lib/graticule/geocoder/rest.rb +110 -0
- data/lib/graticule/geocoder/yahoo.rb +96 -0
- data/lib/graticule/location.rb +19 -7
- data/lib/graticule/version.rb +2 -2
- data/test/fixtures/responses/host_ip/private.txt +4 -0
- data/test/fixtures/responses/host_ip/success.txt +4 -0
- data/test/fixtures/responses/host_ip/unknown.txt +4 -0
- data/test/fixtures/responses/local_search_maps/success.txt +1 -0
- data/test/fixtures/responses/postcode_anywhere/badkey.xml +9 -0
- data/test/fixtures/responses/postcode_anywhere/canada.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/empty.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/success.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/uk.xml +18 -0
- data/test/test_helper.rb +4 -2
- data/test/unit/graticule/geocoder/geocoder_us_test.rb +43 -0
- data/test/unit/graticule/geocoder/google_test.rb +66 -0
- data/test/unit/graticule/geocoder/host_ip_test.rb +39 -0
- data/test/unit/graticule/geocoder/local_search_maps_test.rb +30 -0
- data/test/unit/graticule/geocoder/meta_carta_test.rb +44 -0
- data/test/unit/graticule/geocoder/postcode_anywhere_test.rb +50 -0
- data/test/unit/graticule/geocoder/yahoo_test.rb +48 -0
- data/test/unit/graticule/geocoder_test.rb +5 -9
- data/test/unit/graticule/location_test.rb +22 -7
- metadata +37 -18
- data/lib/graticule/geocoders/bogus.rb +0 -11
- data/lib/graticule/geocoders/geocoder_us.rb +0 -45
- data/lib/graticule/geocoders/google.rb +0 -99
- data/lib/graticule/geocoders/meta_carta.rb +0 -102
- data/lib/graticule/geocoders/rest.rb +0 -98
- data/lib/graticule/geocoders/yahoo.rb +0 -101
- data/test/unit/graticule/geocoders/geocoder_us_test.rb +0 -42
- data/test/unit/graticule/geocoders/geocoders.rb +0 -56
- data/test/unit/graticule/geocoders/google_test.rb +0 -22
- data/test/unit/graticule/geocoders/meta_carta_test.rb +0 -70
- data/test/unit/graticule/geocoders/yahoo_test.rb +0 -49
@@ -1,101 +0,0 @@
|
|
1
|
-
module Graticule #:nodoc:
|
2
|
-
|
3
|
-
# Yahoo geocoding API.
|
4
|
-
#
|
5
|
-
# http://developer.yahoo.com/maps/rest/V1/geocode.html
|
6
|
-
class YahooGeocoder < RestGeocoder
|
7
|
-
|
8
|
-
PRECISION = {
|
9
|
-
"country"=> :country,
|
10
|
-
"state" => :state,
|
11
|
-
"city" => :city,
|
12
|
-
"zip+4" => :zip,
|
13
|
-
"zip+2" => :zip,
|
14
|
-
"zip" => :zip,
|
15
|
-
"street" => :street,
|
16
|
-
"address" => :address
|
17
|
-
}
|
18
|
-
|
19
|
-
# Web services initializer.
|
20
|
-
#
|
21
|
-
# The +appid+ is the Application ID that uniquely identifies your
|
22
|
-
# application. See: http://developer.yahoo.com/faq/index.html#appid
|
23
|
-
#
|
24
|
-
# Concrete web services implementations need to set the following instance
|
25
|
-
# variables then call super:
|
26
|
-
#
|
27
|
-
# +host+:: API endpoint hostname
|
28
|
-
# +service_name+:: service name
|
29
|
-
# +version+:: service name version number
|
30
|
-
# +method+:: service method call
|
31
|
-
#
|
32
|
-
# See http://developer.yahoo.com/search/rest.html
|
33
|
-
def initialize(appid)
|
34
|
-
@host = 'api.local.yahoo.com'
|
35
|
-
@service_name = 'MapsService'
|
36
|
-
@version = 'V1'
|
37
|
-
@method = 'geocode'
|
38
|
-
@appid = appid
|
39
|
-
@url = URI.parse "http://#{@host}/#{@service_name}/#{@version}/#{@method}"
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns a Location for +address+.
|
43
|
-
#
|
44
|
-
# The +address+ can be any of:
|
45
|
-
# * city, state
|
46
|
-
# * city, state, zip
|
47
|
-
# * zip
|
48
|
-
# * street, city, state
|
49
|
-
# * street, city, state, zip
|
50
|
-
# * street, zip
|
51
|
-
def locate(address)
|
52
|
-
get :location => address
|
53
|
-
end
|
54
|
-
|
55
|
-
def parse_response(xml) # :nodoc:
|
56
|
-
locations = []
|
57
|
-
|
58
|
-
xml.elements['ResultSet'].each do |r|
|
59
|
-
location = Location.new
|
60
|
-
|
61
|
-
location.precision = PRECISION[r.attributes['precision']] || :unknown
|
62
|
-
|
63
|
-
if r.attributes.include? 'warning' then
|
64
|
-
location.warning = r.attributes['warning']
|
65
|
-
end
|
66
|
-
|
67
|
-
location.latitude = r.elements['Latitude'].text.to_f
|
68
|
-
location.longitude = r.elements['Longitude'].text.to_f
|
69
|
-
|
70
|
-
location.street = r.elements['Address'].text.titleize unless r.elements['Address'].text.blank?
|
71
|
-
location.city = r.elements['City'].text.titleize unless r.elements['City'].text.blank?
|
72
|
-
location.state = r.elements['State'].text
|
73
|
-
location.zip = r.elements['Zip'].text
|
74
|
-
location.country = r.elements['Country'].text
|
75
|
-
|
76
|
-
locations << location
|
77
|
-
end
|
78
|
-
|
79
|
-
# FIXME: make API consistent and only return 1 location
|
80
|
-
return locations
|
81
|
-
end
|
82
|
-
|
83
|
-
# Extracts and raises an error from +xml+, if any.
|
84
|
-
def check_error(xml) #:nodoc:
|
85
|
-
err = xml.elements['Error']
|
86
|
-
raise Error, err.elements['Message'].text if err
|
87
|
-
end
|
88
|
-
|
89
|
-
# Creates a URL from the Hash +params+. Automatically adds the appid and
|
90
|
-
# sets the output type to 'xml'.
|
91
|
-
def make_url(params) #:nodoc:
|
92
|
-
params[:appid] = @appid
|
93
|
-
params[:output] = 'xml'
|
94
|
-
|
95
|
-
super params
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
-
require File.dirname(__FILE__) + '/geocoders'
|
3
|
-
|
4
|
-
module Graticule
|
5
|
-
class GeocoderUsTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
URI::HTTP.responses = []
|
9
|
-
URI::HTTP.uris = []
|
10
|
-
|
11
|
-
@geocoder = GeocoderUsGeocoder.new
|
12
|
-
@location = Location.new(
|
13
|
-
:street => "1600 Pennsylvania Ave NW, Washington DC 20502",
|
14
|
-
:longitude => -77.037684,
|
15
|
-
:latitude => 38.898748
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_success
|
20
|
-
prepare_response(:success)
|
21
|
-
assert_equal @location, @geocoder.locate('1600 Pennsylvania Ave, Washington DC')
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_url
|
25
|
-
prepare_response(:success)
|
26
|
-
@geocoder.locate('1600 Pennsylvania Ave, Washington DC')
|
27
|
-
assert_equal 'http://rpc.geocoder.us/service/rest/geocode?address=1600%20Pennsylvania%20Ave,%20Washington%20DC',
|
28
|
-
URI::HTTP.uris.first
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_locate_bad_address
|
32
|
-
prepare_response(:unknown)
|
33
|
-
assert_raises(AddressError) { @geocoder.locate('yuck') }
|
34
|
-
end
|
35
|
-
|
36
|
-
protected
|
37
|
-
def prepare_response(id)
|
38
|
-
URI::HTTP.responses << response('geocoder_us', id)
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
-
|
3
|
-
|
4
|
-
module Graticule
|
5
|
-
|
6
|
-
# Generic tests for all geocoders (theoretically)
|
7
|
-
module GeocodersTestCase
|
8
|
-
|
9
|
-
def test_success
|
10
|
-
return unless prepare_response(:success)
|
11
|
-
|
12
|
-
location = Location.new(
|
13
|
-
:street => "1600 Amphitheatre Pkwy",
|
14
|
-
:city => "Mountain View",
|
15
|
-
:state => "CA",
|
16
|
-
:zip => "94043",
|
17
|
-
:country => "US",
|
18
|
-
:longitude => -122.083739,
|
19
|
-
:latitude => 37.423021,
|
20
|
-
:precision => :address
|
21
|
-
)
|
22
|
-
assert_equal location, @geocoder.locate('1600 Amphitheatre Parkway, Mountain View, CA')
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_bad_key
|
26
|
-
return unless prepare_response(:badkey)
|
27
|
-
assert_raises(CredentialsError) { @geocoder.locate('x') }
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_locate_missing_address
|
31
|
-
return unless prepare_response(:missing_address)
|
32
|
-
assert_raises(AddressError) { @geocoder.locate 'x' }
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_locate_server_error
|
36
|
-
return unless prepare_response(:server_error)
|
37
|
-
assert_raises(Error) { @geocoder.locate 'x' }
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_locate_too_many_queries
|
41
|
-
return unless prepare_response(:limit)
|
42
|
-
assert_raises(CredentialsError) { @geocoder.locate 'x' }
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_locate_unavailable_address
|
46
|
-
return unless prepare_response(:unavailable)
|
47
|
-
assert_raises(AddressError) { @geocoder.locate 'x' }
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_locate_unknown_address
|
51
|
-
return unless prepare_response(:unknown_address)
|
52
|
-
assert_raises(AddressError) { @geocoder.locate 'x' }
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
-
require File.dirname(__FILE__) + '/geocoders'
|
3
|
-
|
4
|
-
module Graticule
|
5
|
-
class GoogleGeocoderTest < Test::Unit::TestCase
|
6
|
-
# run tests from GeocodersTest
|
7
|
-
include GeocodersTestCase
|
8
|
-
|
9
|
-
def setup
|
10
|
-
URI::HTTP.responses = []
|
11
|
-
URI::HTTP.uris = []
|
12
|
-
@geocoder = GoogleGeocoder.new(:key => 'APP_ID')
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def prepare_response(id = :success)
|
18
|
-
URI::HTTP.responses << response('google', id)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
-
require File.dirname(__FILE__) + '/geocoders'
|
3
|
-
|
4
|
-
module Graticule
|
5
|
-
class MetaCartaGeocoderTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
URI::HTTP.responses = []
|
9
|
-
URI::HTTP.uris = []
|
10
|
-
|
11
|
-
@geocoder = MetaCartaGeocoder.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_locate
|
15
|
-
prepare_response(:success)
|
16
|
-
|
17
|
-
expected = MetaCartaGeocoder::Location.new 'Baghdad', 'PPLC', 5672516,
|
18
|
-
'Iraq/Baghdad/Baghdad',
|
19
|
-
44.393889, 33.338611, 0.195185,
|
20
|
-
[[26.238611, 37.293889],
|
21
|
-
[40.438611, 51.493889]]
|
22
|
-
|
23
|
-
location = @geocoder.locate('baghdad')
|
24
|
-
assert_equal expected, location
|
25
|
-
assert_equal [44.393889, 33.338611], location.coordinates
|
26
|
-
|
27
|
-
assert_equal true, URI::HTTP.responses.empty?
|
28
|
-
assert_equal 1, URI::HTTP.uris.length
|
29
|
-
assert_equal 'http://labs.metacarta.com/GeoParser/?output=locations&q=baghdad',
|
30
|
-
URI::HTTP.uris.first
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_locate_bad_address
|
34
|
-
prepare_response(:bad_address)
|
35
|
-
assert_raises(AddressError) { @geocoder.locate('aoeueou') }
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_locations
|
39
|
-
prepare_response(:multiple)
|
40
|
-
|
41
|
-
expected = [
|
42
|
-
MetaCartaGeocoder::Location.new('Seattle', 'PPL', 563374,
|
43
|
-
'United States/Washington/King/Seattle',
|
44
|
-
-122.33083, 47.60639, nil,
|
45
|
-
[[43.806390, -126.130830],
|
46
|
-
[51.406390, -118.530830]]),
|
47
|
-
MetaCartaGeocoder::Location.new('Seattle', 'PRT', nil,
|
48
|
-
'United States/Seattle',
|
49
|
-
-122.333333, 47.6, nil,
|
50
|
-
[[43.8, -126.133333],
|
51
|
-
[51.4, -118.533333]]),
|
52
|
-
]
|
53
|
-
|
54
|
-
locations, viewbox = @geocoder.locations('seattle')
|
55
|
-
assert_equal expected, locations
|
56
|
-
assert_equal [[43.8, -126.133333], [51.40639, -118.53083]], viewbox
|
57
|
-
|
58
|
-
assert_equal true, URI::HTTP.responses.empty?
|
59
|
-
assert_equal 1, URI::HTTP.uris.length
|
60
|
-
assert_equal 'http://labs.metacarta.com/GeoParser/?loc=seattle&output=locations',
|
61
|
-
URI::HTTP.uris.first
|
62
|
-
end
|
63
|
-
|
64
|
-
protected
|
65
|
-
def prepare_response(id = :success)
|
66
|
-
URI::HTTP.responses << response('meta_carta', id)
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
-
require File.dirname(__FILE__) + '/geocoders'
|
3
|
-
|
4
|
-
module Graticule
|
5
|
-
class YahooGeocoderTest < Test::Unit::TestCase
|
6
|
-
#include GeocodersTestCase
|
7
|
-
|
8
|
-
def setup
|
9
|
-
URI::HTTP.responses = []
|
10
|
-
URI::HTTP.uris = []
|
11
|
-
@geocoder = YahooGeocoder.new 'APP_ID'
|
12
|
-
@location = Location.new(
|
13
|
-
:street => "701 First Ave",
|
14
|
-
:city => "Sunnyvale",
|
15
|
-
:state => "CA",
|
16
|
-
:zip => "94089-1019",
|
17
|
-
:country => "US",
|
18
|
-
:longitude => -122.024853,
|
19
|
-
:latitude => 37.416384,
|
20
|
-
:precision => :address
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_locate
|
25
|
-
prepare_response(:success)
|
26
|
-
assert_equal [@location], @geocoder.locate('701 First Street, Sunnyvale, CA')
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_url
|
30
|
-
prepare_response(:success)
|
31
|
-
@geocoder.locate('701 First Street, Sunnyvale, CA')
|
32
|
-
assert_equal 'http://api.local.yahoo.com/MapsService/V1/geocode?appid=APP_ID&location=701%20First%20Street,%20Sunnyvale,%20CA&output=xml',
|
33
|
-
URI::HTTP.uris.first
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
def test_locate_bad_address
|
38
|
-
prepare_response(:unknown_address)
|
39
|
-
assert_raise(Error) { @geocoder.locate('yucksthoeusthaoeusnhtaosu') }
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
def prepare_response(id)
|
44
|
-
URI::HTTP.responses << response('yahoo', id)
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|