google-geocode 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright 2006 Eric Hodel, The Robot Co-op. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. Neither the names of the authors nor the names of their contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
17
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ LICENSE
2
+ Manifest.txt
3
+ README
4
+ Rakefile
5
+ lib/google_geocode.rb
6
+ test/test_google_geocode.rb
7
+ test/uri_stub.rb
data/README ADDED
@@ -0,0 +1,35 @@
1
+ = google-geocode
2
+
3
+ Rubyforge Project:
4
+
5
+ http://rubyforge.org/projects/rctools
6
+
7
+ Documentation:
8
+
9
+ http://dev.robotcoop.com/Libraries/google-geocode
10
+
11
+ == About
12
+
13
+ google-geocode implements Google's Geocoding API.
14
+
15
+ == Installing google-geocode
16
+
17
+ Just install the gem:
18
+
19
+ $ sudo gem install google-geocode
20
+
21
+ == Using google-geocode
22
+
23
+ First you need a Google Maps API key. Yuo can register for one here:
24
+
25
+ http://www.google.com/apis/maps/signup.html
26
+
27
+ Then you create a GoogleGeocode object and start locating addresses:
28
+
29
+ require 'rubygems'
30
+ require 'google_geocode'
31
+
32
+ gg = GoogleGeocode.new application_id
33
+ location = gg.locate '1600 Amphitheater Pkwy, Mountain View, CA'
34
+ p location.coordinates
35
+
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+
7
+ $VERBOSE = nil
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'google-geocode'
11
+ s.version = '1.0.0'
12
+ s.summary = 'Google Geocoder API Library'
13
+ s.description = 'Map addresses to latitude and longitude with Google\'s Geocoder.'
14
+ s.author = 'Eric Hodel'
15
+ s.email = 'eric@robotcoop.com'
16
+
17
+ s.has_rdoc = true
18
+ s.files = File.read('Manifest.txt').split($/)
19
+ s.require_path = 'lib'
20
+ end
21
+
22
+ desc 'Run tests'
23
+ task :default => [ :test ]
24
+
25
+ Rake::TestTask.new('test') do |t|
26
+ t.libs << 'test'
27
+ t.pattern = 'test/test_*.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ desc 'Update Manifest.txt'
32
+ task :update_manifest do
33
+ sh "find . -type f | sed -e 's%./%%' | egrep -v 'svn|swp|~' | egrep -v '^(doc|pkg)/' | sort > Manifest.txt"
34
+ end
35
+
36
+ desc 'Generate RDoc'
37
+ Rake::RDocTask.new :rdoc do |rd|
38
+ rd.rdoc_dir = 'doc'
39
+ rd.rdoc_files.add 'lib', 'README', 'LICENSE'
40
+ rd.main = 'README'
41
+ rd.options << '-d' if `which dot` =~ /\/dot/
42
+ rd.options << '-t Google Geocode'
43
+ end
44
+
45
+ desc 'Generate RDoc for dev.robotcoop.com'
46
+ Rake::RDocTask.new :dev_rdoc do |rd|
47
+ rd.rdoc_dir = '../../../www/trunk/dev/html/Libraries/google-geocode'
48
+ rd.rdoc_files.add 'lib', 'README', 'LICENSE'
49
+ rd.main = 'README'
50
+ rd.options << '-d' if `which dot` =~ /\/dot/
51
+ rd.options << '-t Google Geocode'
52
+ end
53
+
54
+ desc 'Build Gem'
55
+ Rake::GemPackageTask.new spec do |pkg|
56
+ pkg.need_tar = true
57
+ end
58
+
59
+ desc 'Clean up'
60
+ task :clean => [ :clobber_rdoc, :clobber_package ]
61
+
62
+ desc 'Clean up'
63
+ task :clobber => [ :clean ]
64
+
65
+ # vim: syntax=Ruby
66
+
@@ -0,0 +1,123 @@
1
+ require 'open-uri'
2
+ require 'rexml/document'
3
+
4
+ ##
5
+ # Library for looking up coordinates with Google's Geocoding API.
6
+ #
7
+ # http://www.google.com/apis/maps/documentation/#Geocoding_HTTP_Request
8
+
9
+ class GoogleGeocode
10
+
11
+ ##
12
+ # Base error class
13
+
14
+ class Error < RuntimeError; end
15
+
16
+ ##
17
+ # Raised when you try to locate an invalid address.
18
+
19
+ class AddressError < Error; end
20
+
21
+ ##
22
+ # Raised when you use an invalid key.
23
+
24
+ class KeyError < Error; end
25
+
26
+ ##
27
+ # Location struct
28
+
29
+ Location = Struct.new :address, :latitude, :longitude
30
+
31
+ ##
32
+ # Creates a new GoogleGeocode that will use Google Maps API key +key+. You
33
+ # can sign up for an API key here:
34
+ #
35
+ # http://www.google.com/apis/maps/signup.html
36
+
37
+ def initialize(key)
38
+ @key = key
39
+ @url = URI.parse 'http://maps.google.com/maps/geo'
40
+ end
41
+
42
+ ##
43
+ # Locates +address+ returning a Location struct.
44
+
45
+ def locate(address)
46
+ get :q => address
47
+ end
48
+
49
+ private
50
+
51
+ def parse_response(xml)
52
+ l = Location.new
53
+
54
+ l.address = xml.elements['/kml/Response/Placemark/address'].text
55
+
56
+ coordinates = xml.elements['/kml/Response/Placemark/Point/coordinates'].text
57
+ l.longitude, l.latitude, = coordinates.split(',').map { |v| v.to_f }
58
+
59
+ return l
60
+ end
61
+
62
+ def check_error(obj)
63
+ obj = REXML::Document.new obj.read unless REXML::Document === obj
64
+
65
+ status = obj.elements['/kml/Response/Status/code'].text.to_i
66
+ case status
67
+ when 200 # ignore, ok
68
+ when 602
69
+ raise AddressError, 'invalid address'
70
+ when 610
71
+ raise KeyError, 'invalid key'
72
+ else
73
+ raise Error, "unknown error #{status}"
74
+ end
75
+ end
76
+
77
+ def get(params)
78
+ url = make_url params
79
+
80
+ url.open do |xml|
81
+ res = REXML::Document.new xml.read
82
+
83
+ check_error res
84
+ return parse_response(res)
85
+ end
86
+ rescue OpenURI::HTTPError => e
87
+ check_error e.io
88
+ raise
89
+ end
90
+
91
+ def make_url(params)
92
+ params[:key] = @key
93
+ params[:output] = 'xml'
94
+
95
+ escaped_params = params.sort_by { |k,v| k.to_s }.map do |k,v|
96
+ "#{URI.escape k.to_s}=#{URI.escape v.to_s}"
97
+ end
98
+
99
+ url = @url.dup
100
+ url.query = escaped_params.join '&'
101
+ return url
102
+ end
103
+
104
+ end
105
+
106
+ ##
107
+ # A Location contains the following fields:
108
+ #
109
+ # +latitude+:: Latitude of the location
110
+ # +longitude+:: Longitude of the location
111
+ # +address+:: Street address of the result.
112
+
113
+ class GoogleGeocode::Location
114
+
115
+ ##
116
+ # The coordinates for this location.
117
+
118
+ def coordinates
119
+ [latitude, longitude]
120
+ end
121
+
122
+ end
123
+
@@ -0,0 +1,74 @@
1
+ require 'test/unit'
2
+ require 'test/uri_stub'
3
+
4
+ require 'google_geocode'
5
+
6
+ class TestGoogleGeocode < Test::Unit::TestCase
7
+
8
+ def setup
9
+ URI::HTTP.responses = []
10
+ URI::HTTP.uris = []
11
+
12
+ @gg = GoogleGeocode.new 'APP_ID'
13
+ end
14
+
15
+ def test_locate
16
+ URI::HTTP.responses << <<-EOF.strip
17
+ <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>1600 Amphitheatre Parkway, Mountain View, CA</name><Status><code>200</code><request>geocode</request></Status><Placemark><address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</address><AddressDetails xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Santa Clara</SubAdministrativeAreaName><Locality><LocalityName>Mountain View</LocalityName><Thoroughfare><ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>94043</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><Point><coordinates>-122.083739,37.423021,0</coordinates></Point></Placemark></Response></kml>
18
+ EOF
19
+
20
+ location = GoogleGeocode::Location.new
21
+ location.address = '1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA'
22
+ location.latitude = 37.423021
23
+ location.longitude = -122.083739
24
+
25
+ assert_equal location,
26
+ @gg.locate('1600 Amphitheatre Parkway, Mountain View, CA')
27
+
28
+ assert_equal true, URI::HTTP.responses.empty?
29
+ assert_equal 1, URI::HTTP.uris.length
30
+ assert_equal 'http://maps.google.com/maps/geo?key=APP_ID&output=xml&q=1600%20Amphitheatre%20Parkway,%20Mountain%20View,%20CA',
31
+ URI::HTTP.uris.first
32
+ end
33
+
34
+ def test_locate_bad_key
35
+ URI::HTTP.responses << <<-EOF.strip
36
+ <?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://earth.google.com/kml/2.0'><Response><name>1600 Amphitheater Pkwy, Mountain View, CA</name><Status><code>610</code><request>geocode</request></Status></Response></kml>
37
+ EOF
38
+
39
+ @gg.locate 'x'
40
+
41
+ rescue GoogleGeocode::KeyError => e
42
+ assert_equal 'invalid key', e.message
43
+ else
44
+ flunk 'Error expected'
45
+ end
46
+
47
+ def test_locate_bad_address
48
+ URI::HTTP.responses << <<-EOF.strip
49
+ <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>1600</name><Status><code>602</code><request>geocode</request></Status></Response></kml>
50
+ EOF
51
+
52
+ @gg.locate 'x'
53
+
54
+ rescue GoogleGeocode::AddressError => e
55
+ assert_equal 'invalid address', e.message
56
+ else
57
+ flunk 'Error expected'
58
+ end
59
+
60
+ end
61
+
62
+ class TestGoogleGeocodeLocation < Test::Unit::TestCase
63
+
64
+ def test_coordinates
65
+ location = GoogleGeocode::Location.new
66
+ location.address = '1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA'
67
+ location.latitude = 37.423021
68
+ location.longitude = -122.083739
69
+
70
+ assert_equal [37.423021, -122.083739], location.coordinates
71
+ end
72
+
73
+ end
74
+
data/test/uri_stub.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'open-uri'
2
+
3
+ class URI::HTTP
4
+
5
+ class << self
6
+ attr_accessor :responses, :uris
7
+ end
8
+
9
+ alias original_open open
10
+
11
+ def open
12
+ self.class.uris << self.to_s
13
+ yield StringIO.new(self.class.responses.shift)
14
+ end
15
+
16
+ end
17
+
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11.15
3
+ specification_version: 1
4
+ name: google-geocode
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2006-06-12 00:00:00 -07:00
8
+ summary: Google Geocoder API Library
9
+ require_paths:
10
+ - lib
11
+ email: eric@robotcoop.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description: Map addresses to latitude and longitude with Google's Geocoder.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Eric Hodel
31
+ files:
32
+ - LICENSE
33
+ - Manifest.txt
34
+ - README
35
+ - Rakefile
36
+ - lib/google_geocode.rb
37
+ - test/test_google_geocode.rb
38
+ - test/uri_stub.rb
39
+ test_files: []
40
+
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies: []
52
+