google-geo 2.1 → 2.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,6 +1,9 @@
1
- = 2.0 Multiple Addresses (and tests you can actually run!)
2
- - Not insignificant API change: *** Google::Geo#locate ALWAYS RETURNS AN ARRAY ***
3
- - There are now some nice examples in the README.
4
- - Updated to include the fixtures and vendor dependencies for tests, yeknow, so you can actually run them.
5
- - No namby pamby point releases. This is serious, folks.
6
- = 1.0 Initial Release
1
+ v2.3. Fixed a bug with parsing accuracy. Thanks to David Vrensk!
2
+
3
+ v2.2. Added reverse locate and optional street view embed features. Thanks to Fernando Barajas and Peter Gassner!
4
+
5
+ v2.1. Added a LICENSE and RubyForge publishing support. Fixed Rakefile.
6
+
7
+ v2.0. Multiple Addresses (and tests you can actually run!); Not insignificant API change: *** Google::Geo#locate ALWAYS RETURNS AN ARRAY ***; There are now some nice examples in the README; Updated to include the fixtures and vendor dependencies for tests, yeknow, so you can actually run them; No namby pamby point releases. This is serious, folks.
8
+
9
+ v1.0. Initial Release
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ This program is free software. It comes without any warranty, to
2
+ the extent permitted by applicable law. You can redistribute it
3
+ and/or modify it under the terms of the Do What The Fuck You Want
4
+ To Public License, Version 2, as published by Sam Hocevar. See
5
+ http://sam.zoy.org/wtfpl/COPYING for more details.
6
+
7
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
8
+ Version 2, December 2004
9
+
10
+ Copyright (C) 2008 Seth Thomas Rasmussen
11
+ Everyone is permitted to copy and distribute verbatim or modified
12
+ copies of this license document, and changing it is allowed as long
13
+ as the name is changed.
14
+
15
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
16
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
17
+
18
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,81 @@
1
+ CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.textile
5
+ Rakefile
6
+ google-geo.gemspec
7
+ lib/google/geo.rb
8
+ lib/google/geo/address.rb
9
+ lib/google/geo/address/street_view.rb
10
+ lib/google/geo/params.rb
11
+ lib/google/geo/parser.rb
12
+ lib/google/geo/response.rb
13
+ script/test_street_view.rb
14
+ test/fixtures/invalid_map_key.xml
15
+ test/fixtures/missing_address.xml
16
+ test/fixtures/reverse_locate_602.xml
17
+ test/fixtures/reverse_locate_success.xml
18
+ test/fixtures/server_error.xml
19
+ test/fixtures/streetview_success.xml
20
+ test/fixtures/success.xml
21
+ test/fixtures/success_english.xml
22
+ test/fixtures/success_german.xml
23
+ test/fixtures/success_with_multiple_addresses.xml
24
+ test/fixtures/too_many_queries.xml
25
+ test/fixtures/unavailable_address.xml
26
+ test/fixtures/unknown_address.xml
27
+ test/geo_test.rb
28
+ test/reverse_locate_test.rb
29
+ test/test_helper.rb
30
+ vendor/mocha-0.4.0/COPYING
31
+ vendor/mocha-0.4.0/MIT-LICENSE
32
+ vendor/mocha-0.4.0/README
33
+ vendor/mocha-0.4.0/RELEASE
34
+ vendor/mocha-0.4.0/Rakefile
35
+ vendor/mocha-0.4.0/examples/misc.rb
36
+ vendor/mocha-0.4.0/examples/mocha.rb
37
+ vendor/mocha-0.4.0/examples/stubba.rb
38
+ vendor/mocha-0.4.0/lib/mocha.rb
39
+ vendor/mocha-0.4.0/lib/mocha/any_instance_method.rb
40
+ vendor/mocha-0.4.0/lib/mocha/auto_verify.rb
41
+ vendor/mocha-0.4.0/lib/mocha/central.rb
42
+ vendor/mocha-0.4.0/lib/mocha/class_method.rb
43
+ vendor/mocha-0.4.0/lib/mocha/expectation.rb
44
+ vendor/mocha-0.4.0/lib/mocha/expectation_error.rb
45
+ vendor/mocha-0.4.0/lib/mocha/infinite_range.rb
46
+ vendor/mocha-0.4.0/lib/mocha/inspect.rb
47
+ vendor/mocha-0.4.0/lib/mocha/instance_method.rb
48
+ vendor/mocha-0.4.0/lib/mocha/metaclass.rb
49
+ vendor/mocha-0.4.0/lib/mocha/mock.rb
50
+ vendor/mocha-0.4.0/lib/mocha/mock_methods.rb
51
+ vendor/mocha-0.4.0/lib/mocha/object.rb
52
+ vendor/mocha-0.4.0/lib/mocha/pretty_parameters.rb
53
+ vendor/mocha-0.4.0/lib/mocha/setup_and_teardown.rb
54
+ vendor/mocha-0.4.0/lib/mocha/standalone.rb
55
+ vendor/mocha-0.4.0/lib/mocha/test_case_adapter.rb
56
+ vendor/mocha-0.4.0/lib/mocha_standalone.rb
57
+ vendor/mocha-0.4.0/lib/stubba.rb
58
+ vendor/mocha-0.4.0/test/active_record_test_case.rb
59
+ vendor/mocha-0.4.0/test/all_tests.rb
60
+ vendor/mocha-0.4.0/test/execution_point.rb
61
+ vendor/mocha-0.4.0/test/method_definer.rb
62
+ vendor/mocha-0.4.0/test/mocha/any_instance_method_test.rb
63
+ vendor/mocha-0.4.0/test/mocha/auto_verify_test.rb
64
+ vendor/mocha-0.4.0/test/mocha/central_test.rb
65
+ vendor/mocha-0.4.0/test/mocha/class_method_test.rb
66
+ vendor/mocha-0.4.0/test/mocha/expectation_test.rb
67
+ vendor/mocha-0.4.0/test/mocha/infinite_range_test.rb
68
+ vendor/mocha-0.4.0/test/mocha/inspect_test.rb
69
+ vendor/mocha-0.4.0/test/mocha/metaclass_test.rb
70
+ vendor/mocha-0.4.0/test/mocha/mock_methods_test.rb
71
+ vendor/mocha-0.4.0/test/mocha/mock_test.rb
72
+ vendor/mocha-0.4.0/test/mocha/object_test.rb
73
+ vendor/mocha-0.4.0/test/mocha/pretty_parameters_test.rb
74
+ vendor/mocha-0.4.0/test/mocha/setup_and_teardown_test.rb
75
+ vendor/mocha-0.4.0/test/mocha_acceptance_test.rb
76
+ vendor/mocha-0.4.0/test/mocha_test_result_integration_test.rb
77
+ vendor/mocha-0.4.0/test/standalone_acceptance_test.rb
78
+ vendor/mocha-0.4.0/test/stubba_acceptance_test.rb
79
+ vendor/mocha-0.4.0/test/stubba_integration_test.rb
80
+ vendor/mocha-0.4.0/test/stubba_test_result_integration_test.rb
81
+ vendor/mocha-0.4.0/test/test_helper.rb
@@ -0,0 +1,57 @@
1
+ h1. Google::Geo
2
+
3
+ A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
4
+
5
+ h2. Examples
6
+
7
+ geo = Google::Geo.new API_KEY
8
+
9
+ addresses = geo.locate '1600 Amphitheatre Parkway, Mountain View, CA'
10
+ addresses.size # 1, :locate always returns an Array
11
+
12
+ address = addresses.first
13
+ address.country # 'US'
14
+ address.city # 'Mountain View'
15
+ address.full_address # '1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA'
16
+ address.query # '1600 Amphitheatre Parkway, Mountain View, CA'
17
+ address.accuracy # 8
18
+ address.coordinates # [-122.084143, 37.421972, 0.0]
19
+
20
+ In the case of sufficiently vague queries, Google::Geo will return more than one:
21
+
22
+ addresses = geo.locate 'hell'
23
+ addresses.size # 2
24
+ addresses.map { |a| a.state } # ['PA', 'NC']
25
+
26
+ You can reverse geocode:
27
+
28
+ address = geo.locate(33.998671, -118.075926).first
29
+ address.city # => Pico Rivera
30
+ address.state # => CA
31
+ address.zip # => 90660
32
+ address.country # => US
33
+ address.full_address # => 4952-4958 Tobias Ave, Pico Rivera, CA 90660, USA
34
+
35
+ You can optionally enable the ability to get street view embed HTML for an Address:
36
+
37
+ require "google/geo/address/street_view"
38
+ address.street_view_html :id => :street_view, :style => "width:640px; height:480px"
39
+
40
+ h2. Options
41
+
42
+ If you need to get the results in another language, you can set it like so:
43
+
44
+ geo = Google::Geo.new API_KEY, "de"
45
+ geo.language = "en"
46
+
47
+ The language code can be anything listed on "http://spreadsheets.google.com/pub?key=p9pdwsai2hDMsLkXsoM05KQ&gid=1":http://spreadsheets.google.com/pub?key=p9pdwsai2hDMsLkXsoM05KQ&gid=1.
48
+
49
+ h2. Contributors
50
+
51
+ * Seth Thomas Rasmussen - "http://greatseth.com":http://greatseth.com
52
+ * Fernando Barajas - "http://fernyb.net":http://fernyb.net
53
+ * Peter Gassner - "http://www.naehrstoff.ch":http://www.naehrstoff.ch
54
+
55
+ h2. License
56
+
57
+ (c) 2007-2009 Seth Thomas Rasmussen and released under the WTFPL. See the LICENSE file for details.
@@ -0,0 +1,32 @@
1
+ README = File.readlines "#{File.dirname __FILE__}/README.textile"
2
+
3
+ require "echoe"
4
+
5
+ class Echoe
6
+ def honor_gitignore!
7
+ self.ignore_pattern = \
8
+ Dir["**/.gitignore"].inject([]) do |pattern,gitignore|
9
+ pattern.concat \
10
+ File.readlines(gitignore).
11
+ map { |line| line.strip }.
12
+ reject { |line| "" == line }.
13
+ map { |glob|
14
+ d = File.dirname(gitignore)
15
+ d == "." ? glob : File.join(d, glob)
16
+ }
17
+ end.flatten.uniq
18
+ end
19
+ end
20
+
21
+ SPEC = Echoe.new "google-geo" do |p|
22
+ p.author = "Seth Thomas Rasmussen"
23
+ p.email = "sethrasmussen@gmail.com"
24
+ p.url = "http://github.com/greatseth/google-geo"
25
+ p.summary = README[2]
26
+ p.honor_gitignore!
27
+ end
28
+
29
+ task :debug_spec do
30
+ require 'yaml'
31
+ y SPEC.to_yaml
32
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{google-geo}
5
+ s.version = "2.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Seth Thomas Rasmussen"]
9
+ s.date = %q{2009-11-19}
10
+ s.description = %q{A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
11
+ }
12
+ s.email = %q{sethrasmussen@gmail.com}
13
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.textile", "lib/google/geo.rb", "lib/google/geo/address.rb", "lib/google/geo/address/street_view.rb", "lib/google/geo/params.rb", "lib/google/geo/parser.rb", "lib/google/geo/response.rb"]
14
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.textile", "Rakefile", "google-geo.gemspec", "lib/google/geo.rb", "lib/google/geo/address.rb", "lib/google/geo/address/street_view.rb", "lib/google/geo/params.rb", "lib/google/geo/parser.rb", "lib/google/geo/response.rb", "script/test_street_view.rb", "test/fixtures/invalid_map_key.xml", "test/fixtures/missing_address.xml", "test/fixtures/reverse_locate_602.xml", "test/fixtures/reverse_locate_success.xml", "test/fixtures/server_error.xml", "test/fixtures/streetview_success.xml", "test/fixtures/success.xml", "test/fixtures/success_english.xml", "test/fixtures/success_german.xml", "test/fixtures/success_with_multiple_addresses.xml", "test/fixtures/too_many_queries.xml", "test/fixtures/unavailable_address.xml", "test/fixtures/unknown_address.xml", "test/geo_test.rb", "test/reverse_locate_test.rb", "test/test_helper.rb", "vendor/mocha-0.4.0/COPYING", "vendor/mocha-0.4.0/MIT-LICENSE", "vendor/mocha-0.4.0/README", "vendor/mocha-0.4.0/RELEASE", "vendor/mocha-0.4.0/Rakefile", "vendor/mocha-0.4.0/examples/misc.rb", "vendor/mocha-0.4.0/examples/mocha.rb", "vendor/mocha-0.4.0/examples/stubba.rb", "vendor/mocha-0.4.0/lib/mocha.rb", "vendor/mocha-0.4.0/lib/mocha/any_instance_method.rb", "vendor/mocha-0.4.0/lib/mocha/auto_verify.rb", "vendor/mocha-0.4.0/lib/mocha/central.rb", "vendor/mocha-0.4.0/lib/mocha/class_method.rb", "vendor/mocha-0.4.0/lib/mocha/expectation.rb", "vendor/mocha-0.4.0/lib/mocha/expectation_error.rb", "vendor/mocha-0.4.0/lib/mocha/infinite_range.rb", "vendor/mocha-0.4.0/lib/mocha/inspect.rb", "vendor/mocha-0.4.0/lib/mocha/instance_method.rb", "vendor/mocha-0.4.0/lib/mocha/metaclass.rb", "vendor/mocha-0.4.0/lib/mocha/mock.rb", "vendor/mocha-0.4.0/lib/mocha/mock_methods.rb", "vendor/mocha-0.4.0/lib/mocha/object.rb", "vendor/mocha-0.4.0/lib/mocha/pretty_parameters.rb", "vendor/mocha-0.4.0/lib/mocha/setup_and_teardown.rb", "vendor/mocha-0.4.0/lib/mocha/standalone.rb", "vendor/mocha-0.4.0/lib/mocha/test_case_adapter.rb", "vendor/mocha-0.4.0/lib/mocha_standalone.rb", "vendor/mocha-0.4.0/lib/stubba.rb", "vendor/mocha-0.4.0/test/active_record_test_case.rb", "vendor/mocha-0.4.0/test/all_tests.rb", "vendor/mocha-0.4.0/test/execution_point.rb", "vendor/mocha-0.4.0/test/method_definer.rb", "vendor/mocha-0.4.0/test/mocha/any_instance_method_test.rb", "vendor/mocha-0.4.0/test/mocha/auto_verify_test.rb", "vendor/mocha-0.4.0/test/mocha/central_test.rb", "vendor/mocha-0.4.0/test/mocha/class_method_test.rb", "vendor/mocha-0.4.0/test/mocha/expectation_test.rb", "vendor/mocha-0.4.0/test/mocha/infinite_range_test.rb", "vendor/mocha-0.4.0/test/mocha/inspect_test.rb", "vendor/mocha-0.4.0/test/mocha/metaclass_test.rb", "vendor/mocha-0.4.0/test/mocha/mock_methods_test.rb", "vendor/mocha-0.4.0/test/mocha/mock_test.rb", "vendor/mocha-0.4.0/test/mocha/object_test.rb", "vendor/mocha-0.4.0/test/mocha/pretty_parameters_test.rb", "vendor/mocha-0.4.0/test/mocha/setup_and_teardown_test.rb", "vendor/mocha-0.4.0/test/mocha_acceptance_test.rb", "vendor/mocha-0.4.0/test/mocha_test_result_integration_test.rb", "vendor/mocha-0.4.0/test/standalone_acceptance_test.rb", "vendor/mocha-0.4.0/test/stubba_acceptance_test.rb", "vendor/mocha-0.4.0/test/stubba_integration_test.rb", "vendor/mocha-0.4.0/test/stubba_test_result_integration_test.rb", "vendor/mocha-0.4.0/test/test_helper.rb"]
15
+ s.homepage = %q{http://github.com/greatseth/google-geo}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Google-geo", "--main", "README.textile"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{google-geo}
19
+ s.rubygems_version = %q{1.3.5}
20
+ s.summary = %q{A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!}
21
+ s.test_files = ["test/geo_test.rb", "test/reverse_locate_test.rb", "test/test_helper.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -1,183 +1,48 @@
1
- require 'open-uri'
1
+ require "open-uri"
2
+ require "google/geo/params"
3
+ require "google/geo/response"
4
+ require "google/geo/address"
2
5
 
3
6
  module Google
4
-
5
- # = Google::Geo
6
- #
7
- # A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
8
- #
9
- # == Examples
10
- #
11
- # geo = Google::Geo.new API_KEY
12
- #
13
- # addresses = geo.locate '1600 Amphitheatre Parkway, Mountain View, CA'
14
- #
15
- # addresses.size # 1, :locate always returns an Array
16
- #
17
- # address = addresses.first
18
- #
19
- # address.country # 'US'
20
- # address.city # 'Mountain View'
21
- # address.full_address # '1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA'
22
- #
23
- # address.query # '1600 Amphitheatre Parkway, Mountain View, CA'
24
- # address.accuracy # 8
25
- #
26
- # In the case of sufficiently vague queries, Google will return more than one address:
27
- #
28
- # addresses = geo.locate 'heaven'
29
- #
30
- # addresses.size # 2
31
- # addresses.map { |a| a.state } # ['PA', 'NC']
32
- #
33
- # == Contributors
34
- #
35
- # Seth Thomas Rasmussen - http://sethrasmussen.com - sethrasmussen@gmail.com
36
- class Geo
7
+ # Please see README for usage examples.
8
+ class Geo
37
9
  # API key provided by Google allowing access to the Geocode API
38
- attr_accessor :key
39
-
40
- def initialize(key)
41
- @key = key
42
- end
43
-
44
- # Returns an array of Address objects, each with accessors for all the components of a location.
45
- # The query argument should be a string.
46
- def locate(query)
47
- xml = open(uri(query)).read
48
- res = Response.new(xml, key)
49
-
50
- res.placemarks.map { |place| Address.new place, res.query }
51
- end
10
+ attr_accessor :key, :language
52
11
 
53
- # Generate a request URI from a given search string.
54
- def uri(address) #:nodoc:
55
- "http://maps.google.com/maps/geo?q=#{URI.escape address}&key=#{key}&output=xml"
56
- end
57
- private :uri
12
+ # The last response received after a :locate call
13
+ attr_reader :last_response
14
+
15
+ # Google's XML files state that they are utf-8 encoded which is not true.
16
+ # Because they state this explicitly, I see no need to let users set
17
+ # another charset.
18
+ CHARSET = "utf-8"
19
+ def charset; CHARSET; end
58
20
 
59
- ###
21
+ DEFAULT_LANGUAGE = "en"
60
22
 
61
- module Parser #:nodoc:
62
- # Fetch contents of an XML element of the response.
63
- def fetch(element) #:nodoc:
64
- @xml.slice %r{<#{element}>(.+?)</#{element}>}, 1
65
- end
66
-
67
- # Like fetch, but for the only piece of data locked away in an attribute.
68
- def fetch_accuracy #:nodoc:
69
- @xml.slice(%r{Accuracy="([^"]+)">}, 1).to_i
70
- end
23
+ def initialize(key, language = DEFAULT_LANGUAGE)
24
+ @key = key
25
+ @language = language
71
26
  end
72
-
73
- ###
74
-
75
- # Represents locations returned in response to geocoding queries.
76
- class Address
77
- include Parser
78
-
79
- attr_reader :street
80
- alias :thoroughfare :street
81
-
82
- attr_reader :city
83
- alias :locality :city
84
-
85
- attr_reader :zip
86
- alias :postal_code :zip
87
27
 
88
- attr_reader :county
89
- alias :subadministrative_area :county
90
-
91
- attr_reader :state
92
- alias :administrative_area :state
93
-
94
- attr_reader :country
95
- alias :country_code :country
96
-
97
- # An array containing the standard three elements of a coordinate triple: latitude, longitude, elevation.
98
- attr_reader :coordinates
99
-
100
- # A float, the standard first element of a coordinate triple.
101
- attr_reader :longitude
102
- alias :lng :longitude
103
-
104
- # A float, the standard second element of a coordinate triple.
105
- attr_reader :latitude
106
- alias :lat :latitude
107
-
108
- # A float, the standard third element of a coordinate triple.
109
- attr_reader :elevation
110
-
111
- # An integer, Google's rating of the accuracy of the supplied address.
112
- attr_reader :accuracy
113
-
114
- # All address attributes as one string, formatted by the service.
115
- attr_reader :full_address
116
- alias :to_s :full_address
117
-
118
- # The address query sent to the service. i.e. The user input.
119
- attr_reader :query
120
-
121
- def initialize(placemark, query) #:nodoc
122
- @xml = placemark
123
- @query = query
124
-
125
- {
126
- :@street => :ThoroughfareName,
127
- :@city => :LocalityName,
128
- :@zip => :PostalCodeNumber,
129
- :@county => :SubAdministrativeAreaName,
130
- :@state => :AdministrativeAreaName,
131
- :@country => :CountryNameCode,
132
-
133
- :@full_address => :address
134
- }.each do |attribute, element|
135
- instance_variable_set(attribute, (fetch(element) rescue nil))
136
- end
137
-
138
- @longitude, @latitude, @elevation = @coordinates = fetch(:coordinates).split(',').map { |x| x.to_f }
139
-
140
- @accuracy = fetch_accuracy
141
- end
28
+ # >> geo.locate "1600 Pennsylvania Ave"
29
+ #
30
+ # # reverse locate
31
+ # >> geo.locate 33.998671, -118.075926
32
+ #
33
+ # Returns an array of Address objects,
34
+ # each with accessors for all the components of a location.
35
+ def locate(*params)
36
+ @last_response = Response.new(self, Params.new(self, *params))
37
+ @last_response.addresses
142
38
  end
143
39
 
144
40
  ###
145
41
 
146
- class Response #:nodoc:
147
- include Parser
148
-
149
- attr_reader :query, :status, :placemarks
150
-
151
- def initialize(xml, geo_key) #:nodoc
152
- @xml, @geo_key = xml, geo_key
153
-
154
- @query = fetch(:name)
155
- @status = fetch(:code).to_i
156
-
157
- check_for_errors
158
-
159
- @placemarks = @xml.scan %r{<Placemark(?: id="p\d+")?>.+?</Placemark>}m
160
- end
161
-
162
- def check_for_errors #:nodoc:
163
- case status
164
- when 200 then # Success
165
- when 500 then raise ServerError, "Unknown error from Google's server"
166
- when 601 then raise MissingAddressError, "Missing address"
167
- when 602 then raise UnknownAddressError, "Unknown address: #{@query}"
168
- when 603 then raise UnavailableAddressError, "Unavailable address: #{@query}"
169
- when 610 then raise InvalidMapKeyError, "Invalid map key: #{@geo_key}"
170
- when 620 then raise TooManyQueriesError, "Too many queries for map key: #{@geo_key}"
171
- else raise UnknownError, "Unknown error: #{@status}"
172
- end
173
- end
174
- end
175
-
176
- ###
177
-
178
42
  class Error < Exception; end
179
43
 
180
- class ServerError < Error; end
44
+ class ServerError < Error; end
45
+ class BadRequestError < Error; end
181
46
 
182
47
  class AddressError < Error; end
183
48
  class MissingAddressError < AddressError; end
@@ -0,0 +1,75 @@
1
+ require "google/geo/parser"
2
+
3
+ module Google
4
+ class Geo
5
+ # Represents locations returned in response to geocoding queries.
6
+ class Address
7
+ include Parser
8
+
9
+ attr_reader :street
10
+ alias :thoroughfare :street
11
+
12
+ attr_reader :city
13
+ alias :locality :city
14
+
15
+ attr_reader :zip
16
+ alias :postal_code :zip
17
+
18
+ attr_reader :county
19
+ alias :subadministrative_area :county
20
+
21
+ attr_reader :state
22
+ alias :administrative_area :state
23
+
24
+ attr_reader :country
25
+ alias :country_code :country
26
+
27
+ # An array containing the standard three elements of a coordinate triple: latitude, longitude, elevation.
28
+ attr_reader :coordinates
29
+
30
+ # A float, the standard first element of a coordinate triple.
31
+ attr_reader :longitude
32
+ alias :lng :longitude
33
+
34
+ # A float, the standard second element of a coordinate triple.
35
+ attr_reader :latitude
36
+ alias :lat :latitude
37
+
38
+ # A float, the standard third element of a coordinate triple.
39
+ attr_reader :elevation
40
+
41
+ # An integer, Google's rating of the accuracy of the supplied address.
42
+ attr_reader :accuracy
43
+
44
+ # All address attributes as one string, formatted by the service.
45
+ attr_reader :full_address
46
+ alias :to_s :full_address
47
+
48
+ # The address query sent to the service. i.e. The user input.
49
+ attr_reader :query
50
+
51
+ def initialize(placemark, query, geo) #:nodoc
52
+ @geo = geo
53
+ @xml = placemark
54
+ @query = query
55
+
56
+ { :@street => :ThoroughfareName,
57
+ :@city => :LocalityName,
58
+ :@zip => :PostalCodeNumber,
59
+ :@county => :SubAdministrativeAreaName,
60
+ :@state => :AdministrativeAreaName,
61
+ :@country => :CountryNameCode,
62
+
63
+ :@full_address => :address
64
+ }.each do |attribute, element|
65
+ instance_variable_set(attribute, (fetch(element) rescue nil))
66
+ end
67
+
68
+ @longitude, @latitude, @elevation =
69
+ @coordinates = fetch(:coordinates).split(",").map { |x| x.to_f }
70
+
71
+ @accuracy = fetch_accuracy
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,28 @@
1
+ require "google/geo"
2
+
3
+ module Google
4
+ class Geo
5
+ class Address
6
+ # This is a shady method which relies on an unofficial Google API.
7
+ # Use at your own risk!
8
+ def street_view_html(options = {})
9
+ %{<embed id="#{options[:id] or 'google-geo-streetview'}"
10
+ style="#{options[:style]}"
11
+ src="http://maps.google.com/mapfiles/cb/googlepano.066.swf"
12
+ quality="high" wmode="opaque" swliveconnect="false"
13
+ allowscriptaccess="always" type="application/x-shockwave-flash"
14
+ pluginspage="http://www.macromedia.com/go/getflashplayer"
15
+ scale="noscale" salign="lt"
16
+ flashvars="panoId=#{street_view_pano_id}&amp;directionMap=N:N,W:W,S:S,E:E,NW:NW,NE:NE,SW:SW,SE:SE&amp;yaw=0&amp;zoom=0&amp;browser=3&amp;pitch=5&amp;viewerId=1&amp;context=api&amp;animateOnLoad=false&amp;useSsl=false"
17
+ ></embed>}.gsub("\n", "").squeeze(" ")
18
+ end
19
+
20
+ private
21
+ def street_view_pano_id
22
+ url = "http://maps.google.com/cbk?output=xml&oe=utf-8&cb_client=api&ll=#{lat},#{lng}"
23
+ # "&callback=_xdc_._0fqdyf9p2"
24
+ open(url).read.slice(/pano_id="([^"]+)"/, 1)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,44 @@
1
+ module Google
2
+ class Geo
3
+ class Params < Hash
4
+ def initialize(geo, *args)
5
+ @geo = geo
6
+
7
+ params = { :key => @geo.key, :output => "xml", :hl => @geo.language, :oe => "utf-8" }
8
+
9
+ query = case args.size
10
+ when 1
11
+ case args
12
+ when String then args
13
+ when Array then args.join(",")
14
+ end
15
+ when 2
16
+ args.join(",")
17
+ else
18
+ raise ArgumentError, "dunno what to do with #{args.inspect}"
19
+ end
20
+
21
+ params[:q] = query
22
+
23
+ replace params
24
+ end
25
+
26
+ def to_uri
27
+ uri = "http://maps.google.com/maps/geo?" <<
28
+ map { |k,v| "#{k}=#{URI.escape v.to_s}" }.join("&")
29
+ # puts uri
30
+ uri
31
+ end
32
+
33
+ def extract_dimensions!
34
+ if size = delete(:size)
35
+ size.split("x")
36
+ elsif self[:width] and self[:height]
37
+ [delete(:width), delete(:height)]
38
+ else
39
+ [500, 300]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ #:stopdoc:
2
+ module Google
3
+ class Geo
4
+
5
+ module Parser
6
+ # Fetch contents of an XML element of the response.
7
+ def fetch(element)
8
+ @xml.slice(%r{<#{element}>(.+?)</#{element}>}, 1)
9
+ end
10
+
11
+ # Like fetch, but for the only piece of data locked away in an attribute.
12
+ def fetch_accuracy
13
+ @xml.slice(%r{Accuracy="([^"]+)"}, 1).to_i
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ #:startdoc:
@@ -0,0 +1,43 @@
1
+ require "google/geo/parser"
2
+
3
+ #:stopdoc:
4
+ module Google
5
+ class Geo
6
+
7
+ class Response #:nodoc:
8
+ include Parser
9
+
10
+ attr_reader :geo, :params, :xml, :query, :status
11
+
12
+ def initialize(geo, params) #:nodoc
13
+ @geo = geo
14
+
15
+ @params = params
16
+ @xml = open(params.to_uri).read
17
+
18
+ @query = fetch(:name)
19
+ @status = fetch(:code).to_i
20
+
21
+ case @status
22
+ when 200 then # Success
23
+ when 500 then raise ServerError, "Unknown error from Google's server"
24
+ when 601 then raise MissingAddressError, "Missing address"
25
+ when 602 then raise UnknownAddressError, "Unknown address: #{@query}"
26
+ when 603 then raise UnavailableAddressError, "Unavailable address: #{@query}"
27
+ when 610 then raise InvalidMapKeyError, "Invalid map key: #{@geo.key}"
28
+ when 620 then raise TooManyQueriesError, "Too many queries for map key: #{@geo.key}"
29
+ when 400 then raise BadRequestError, "Bad request: #{@status}"
30
+ else raise UnknownError, "Unknown error: #{@status}"
31
+ end
32
+
33
+ @placemarks = @xml.scan %r{<Placemark(?: id="p\d+")?>.+?</Placemark>}m
34
+ end
35
+
36
+ def addresses
37
+ @placemarks.map { |p| Address.new p, @query, @geo }
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ #:startdoc:
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.dirname(__FILE__) + "/../.irbrc"
4
+ enable_street_view
5
+
6
+ g = new_geo
7
+ a = g.locate(*ARGV).first
8
+
9
+ require "tempfile"
10
+
11
+ p = File.expand_path "google-geo-streetview.html"
12
+
13
+ File.open(p, "w") do |f|
14
+ html = a.street_view_html(
15
+ :id => "TEST",
16
+ :style => "width:640px; height:480px"
17
+ )
18
+ f.puts html
19
+ end
20
+
21
+ raise "wtf" and exit unless File.exist? p
22
+
23
+ require "rubygems"
24
+ require "launchy"
25
+ Launchy::Browser.run "file://#{p}"
26
+
27
+ puts "created test file at #{p}"
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <kml xmlns="http://earth.google.com/kml/2.0">
3
+ <Response>
4
+ <name>0.000000,0.000000</name>
5
+ <Status>
6
+ <code>602</code>
7
+ <request>geocode</request>
8
+ </Status>
9
+ </Response>
10
+ </kml>
@@ -0,0 +1,64 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <kml xmlns="http://earth.google.com/kml/2.0"><Response>
3
+ <name>33.998671,-118.075926</name>
4
+ <Status>
5
+ <code>200</code>
6
+ <request>geocode</request>
7
+ </Status>
8
+ <Placemark id="p1">
9
+ <address>4952-4958 Tobias Ave, Pico Rivera, CA 90660, USA</address>
10
+ <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><Locality><LocalityName>Pico Rivera</LocalityName><Thoroughfare><ThoroughfareName>4952-4958 Tobias Ave</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>90660</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
11
+ <ExtendedData>
12
+ <LatLonBox north="34.0018448" south="33.9955496" east="-118.0728908" west="-118.0791860" />
13
+ </ExtendedData>
14
+ <Point><coordinates>-118.0760384,33.9986972,0</coordinates></Point>
15
+ </Placemark>
16
+ <Placemark id="p2">
17
+ <address>Pico Rivera, CA 90660, USA</address>
18
+ <AddressDetails Accuracy="5" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><Locality><LocalityName>Pico Rivera</LocalityName><PostalCode><PostalCodeNumber>90660</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
19
+ <ExtendedData>
20
+ <LatLonBox north="34.0230350" south="33.9502470" east="-118.0515550" west="-118.1211040" />
21
+ </ExtendedData>
22
+ <Point><coordinates>-118.0947106,33.9870228,0</coordinates></Point>
23
+ </Placemark>
24
+ <Placemark id="p3">
25
+ <address>Pico Rivera, CA, USA</address>
26
+ <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><Locality><LocalityName>Pico Rivera</LocalityName></Locality></AdministrativeArea></Country></AddressDetails>
27
+ <ExtendedData>
28
+ <LatLonBox north="34.0303260" south="33.9504570" east="-118.0386930" west="-118.1230050" />
29
+ </ExtendedData>
30
+ <Point><coordinates>-118.0838360,34.0014100,0</coordinates></Point>
31
+ </Placemark>
32
+ <Placemark id="p4">
33
+ <address>Whittier, California, USA</address>
34
+ <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><AddressLine>Whittier</AddressLine></AdministrativeArea></Country></AddressDetails>
35
+ <ExtendedData>
36
+ <LatLonBox north="34.0338340" south="33.8733970" east="-117.9152740" west="-118.1227020" />
37
+ </ExtendedData>
38
+ <Point><coordinates>-118.0420282,33.9743790,0</coordinates></Point>
39
+ </Placemark>
40
+ <Placemark id="p5">
41
+ <address>Los Angeles, California, USA</address>
42
+ <AddressDetails Accuracy="3" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><AddressLine>Los Angeles</AddressLine></AdministrativeArea></Country></AddressDetails>
43
+ <ExtendedData>
44
+ <LatLonBox north="34.8232710" south="32.7500400" east="-117.6457480" west="-118.9517210" />
45
+ </ExtendedData>
46
+ <Point><coordinates>-118.1122679,34.3871821,0</coordinates></Point>
47
+ </Placemark>
48
+ <Placemark id="p6">
49
+ <address>California, USA</address>
50
+ <AddressDetails Accuracy="2" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName></AdministrativeArea></Country></AddressDetails>
51
+ <ExtendedData>
52
+ <LatLonBox north="42.0095190" south="32.5288320" east="-114.1312120" west="-124.4820030" />
53
+ </ExtendedData>
54
+ <Point><coordinates>-119.4179324,36.7782610,0</coordinates></Point>
55
+ </Placemark>
56
+ <Placemark id="p7">
57
+ <address>United States</address>
58
+ <AddressDetails Accuracy="1" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName></Country></AddressDetails>
59
+ <ExtendedData>
60
+ <LatLonBox north="71.4343570" south="17.8315100" east="-65.1685040" west="172.3478480" />
61
+ </ExtendedData>
62
+ <Point><coordinates>-95.7128910,37.0902400,0</coordinates></Point>
63
+ </Placemark>
64
+ </Response></kml>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?><panorama><data_properties image_width="3328" image_height="1664" tile_width="512" tile_height="512" pano_id="R-9UTGfykhiRU89z1P466Q" num_zoom_levels="3" lat="34.154961" lng="-118.255140" ><copyright>© 2009 Google</copyright><text>N Brand Blvd</text><street_range>605</street_range><region>Glendale, CA</region><country>United States</country></data_properties><projection_properties projection_type="spherical" pano_yaw_deg="178.54" tilt_yaw_deg="22.31" tilt_pitch_deg="1.75" /><annotation_properties ><link yaw_deg="353.56" pano_id="tMLR2xMOaxaZbTifZ9VWyw" road_argb="0x80fffa73" ><link_text>N Brand Blvd</link_text></link><link yaw_deg="173.56" pano_id="WPiYdHCB20PymRorUYeWIQ" road_argb="0x80fffa73" ><link_text>N Brand Blvd</link_text></link></annotation_properties></panorama>
@@ -8,7 +8,7 @@
8
8
  </Status>
9
9
  <Placemark>
10
10
  <address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</address>
11
- <AddressDetails xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" Accuracy="8">
11
+ <AddressDetails xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" Accuracy="8" foo="bar">
12
12
  <Country>
13
13
  <CountryNameCode>US</CountryNameCode>
14
14
  <AdministrativeArea>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <kml xmlns="http://earth.google.com/kml/2.0">
3
+ <Response>
4
+ <name>Zürich, Schweiz</name>
5
+ <Status>
6
+ <code>200</code>
7
+ <request>geocode</request>
8
+ </Status>
9
+ <Placemark id="p1">
10
+ <address>Zürich, Switzerland</address>
11
+ <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
12
+ <Country>
13
+ <CountryNameCode>CH</CountryNameCode>
14
+ <CountryName>Switzerland</CountryName>
15
+ <AdministrativeArea>
16
+ <AdministrativeAreaName>Zurich</AdministrativeAreaName>
17
+ <SubAdministrativeArea>
18
+ <SubAdministrativeAreaName>Zurich</SubAdministrativeAreaName>
19
+ <Locality>
20
+ <LocalityName>Zürich</LocalityName>
21
+ </Locality>
22
+ </SubAdministrativeArea>
23
+ </AdministrativeArea>
24
+ </Country>
25
+ </AddressDetails>
26
+ <ExtendedData>
27
+ <LatLonBox north="47.4347210" south="47.3201830" east="8.6254420" west="8.4480810" />
28
+ </ExtendedData>
29
+ <Point>
30
+ <coordinates>8.5380326,47.3690239,0</coordinates>
31
+ </Point>
32
+ </Placemark>
33
+ </Response>
34
+ </kml>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <kml xmlns="http://earth.google.com/kml/2.0">
3
+ <Response>
4
+ <name>Zürich, Schweiz</name>
5
+ <Status>
6
+ <code>200</code>
7
+ <request>geocode</request>
8
+ </Status>
9
+ <Placemark id="p1">
10
+ <address>Zürich, Schweiz</address>
11
+ <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
12
+ <Country>
13
+ <CountryNameCode>CH</CountryNameCode>
14
+ <CountryName>Schweiz</CountryName>
15
+ <AdministrativeArea>
16
+ <AdministrativeAreaName>Zürich</AdministrativeAreaName>
17
+ <SubAdministrativeArea>
18
+ <SubAdministrativeAreaName>Zürich</SubAdministrativeAreaName>
19
+ <Locality>
20
+ <LocalityName>Zürich</LocalityName>
21
+ </Locality>
22
+ </SubAdministrativeArea>
23
+ </AdministrativeArea>
24
+ </Country>
25
+ </AddressDetails>
26
+ <ExtendedData>
27
+ <LatLonBox north="47.4347210" south="47.3201830" east="8.6254420" west="8.4480810" />
28
+ </ExtendedData>
29
+ <Point>
30
+ <coordinates>8.5380326,47.3690239,0</coordinates>
31
+ </Point>
32
+ </Placemark>
33
+ </Response>
34
+ </kml>
@@ -1,18 +1,14 @@
1
- require 'test/unit'
2
- $:.unshift "#{File.dirname __FILE__}/../vendor/mocha-0.4.0/lib"
3
- require 'mocha'
4
- require "#{File.dirname __FILE__}/../lib/google/geo"
1
+ require "test_helper"
5
2
 
6
- class Google::GeoTest < Test::Unit::TestCase
3
+ class GeoTest < Test::Unit::TestCase
7
4
  def setup
8
5
  @geo = Google::Geo.new 'API_KEY'
9
6
  end
10
7
 
11
8
  def test_success
12
- @geo.expects(:open).
9
+ stub_response! :success
13
10
  # show that query is escaped
14
- with("http://maps.google.com/maps/geo?q=1600%20Amphitheatre%20Parkway,%20Mountain%20View,%20CA&key=API_KEY&output=xml").
15
- returns(response(:success))
11
+ # with("http://maps.google.com/maps/geo?q=1600%20Amphitheatre%20Parkway,%20Mountain%20View,%20CA&key=API_KEY&output=xml&hl=en&oe=utf-8").
16
12
 
17
13
  query = '1600 Amphitheatre Parkway, Mountain View, CA'
18
14
 
@@ -53,7 +49,7 @@ class Google::GeoTest < Test::Unit::TestCase
53
49
  end
54
50
 
55
51
  def test_success_with_multiple_addresses
56
- @geo.expects(:open).returns(response(:success_with_multiple_addresses))
52
+ stub_response! :success_with_multiple_addresses
57
53
 
58
54
  heavens = @geo.locate('heaven')
59
55
 
@@ -64,39 +60,55 @@ class Google::GeoTest < Test::Unit::TestCase
64
60
 
65
61
  heavens.each { |h| assert_kind_of Google::Geo::Address, h }
66
62
  end
67
-
63
+
64
+ def test_has_an_accessible_language_attribute_defaulting_to_english
65
+ assert_equal 'en', @geo.language
66
+ @geo.language = 'de'
67
+ assert_equal 'de', @geo.language
68
+ end
69
+
70
+ def test_can_get_results_in_german
71
+ stub_response! :success_german
72
+ # with("http://maps.google.com/maps/geo?q=Z%C3%BCrich,%20Schweiz&key=API_KEY&output=xml&hl=de&oe=utf-8").
73
+ @geo.language = 'de'
74
+ address = @geo.locate('Zürich, Schweiz').first
75
+ assert_equal 'Zürich, Schweiz', address.full_address
76
+ end
77
+
78
+ def test_gets_english_results_by_default
79
+ stub_response! :success_english
80
+ # with("http://maps.google.com/maps/geo?q=Z%C3%BCrich,%20Schweiz&key=API_KEY&output=xml&hl=en&oe=utf-8").
81
+ address = @geo.locate('Zürich, Schweiz').first
82
+ assert_equal 'Zürich, Switzerland', address.full_address
83
+ end
84
+
68
85
  def test_invalid_map_key
69
- @geo.expects(:open).returns(response(:invalid_map_key))
86
+ stub_response! :invalid_map_key
70
87
  assert_raises(Google::Geo::InvalidMapKeyError) { @geo.locate 'foo' }
71
88
  end
72
89
 
73
90
  def test_missing_address
74
- @geo.expects(:open).returns(response(:missing_address))
91
+ stub_response! :missing_address
75
92
  assert_raises(Google::Geo::MissingAddressError) { @geo.locate 'foo' }
76
93
  end
77
94
 
78
95
  def test_server_error
79
- @geo.expects(:open).returns(response(:server_error))
96
+ stub_response! :server_error
80
97
  assert_raises(Google::Geo::ServerError) { @geo.locate 'foo' }
81
98
  end
82
99
 
83
100
  def test_too_many_queries
84
- @geo.expects(:open).returns(response(:too_many_queries))
101
+ stub_response! :too_many_queries
85
102
  assert_raises(Google::Geo::TooManyQueriesError) { @geo.locate 'foo' }
86
103
  end
87
104
 
88
105
  def test_unavailable_address
89
- @geo.expects(:open).returns(response(:unavailable_address))
106
+ stub_response! :unavailable_address
90
107
  assert_raises(Google::Geo::UnavailableAddressError) { @geo.locate 'foo' }
91
108
  end
92
109
 
93
110
  def test_unknown_address
94
- @geo.expects(:open).returns(response(:unknown_address))
111
+ stub_response! :unknown_address
95
112
  assert_raises(Google::Geo::UnknownAddressError) { @geo.locate 'foo' }
96
113
  end
97
-
98
- private
99
- def response(filename)
100
- File.new "#{File.dirname __FILE__}/fixtures/#{filename}.xml"
101
- end
102
114
  end
@@ -0,0 +1,64 @@
1
+ require "test_helper"
2
+
3
+ class ReverseLocateTest < Test::Unit::TestCase
4
+ def setup
5
+ @geo = Google::Geo.new 'API_KEY'
6
+ end
7
+
8
+ def test_should_locate_with_latlon
9
+ stub_response! :reverse_locate_success
10
+ # with("http://maps.google.com/maps/geo?ll=33.998671,-118.075926&key=API_KEY&output=xml&hl=en&oe=utf-8").
11
+
12
+ location = @geo.locate(33.998671, -118.075926)
13
+
14
+ address = location.first
15
+
16
+ assert_equal 33.9986972, address.latitude
17
+ assert_equal -118.0760384, address.longitude
18
+
19
+ assert_equal address.longitude, address.lng
20
+ assert_equal address.latitude, address.lat
21
+ end
22
+
23
+ def test_should_have_city
24
+ stub_response! :reverse_locate_success
25
+ location = @geo.locate(33.998671, -118.075926)
26
+ address = location.first
27
+ assert_equal "Pico Rivera", address.city
28
+ end
29
+
30
+ def test_should_have_two_letter_state
31
+ stub_response! :reverse_locate_success
32
+ location = @geo.locate(33.998671, -118.075926)
33
+ address = location.first
34
+ assert_equal "CA", address.state
35
+ end
36
+
37
+ def test_should_have_zipcode
38
+ stub_response! :reverse_locate_success
39
+ location = @geo.locate(33.998671, -118.075926)
40
+ address = location.first
41
+ assert_equal "90660", address.zip
42
+ end
43
+
44
+ def test_should_have_country
45
+ stub_response! :reverse_locate_success
46
+ location = @geo.locate(33.998671, -118.075926)
47
+ address = location.first
48
+ assert_equal "US", address.country
49
+ end
50
+
51
+ def test_should_have_full_address
52
+ stub_response! :reverse_locate_success
53
+ location = @geo.locate(33.998671, -118.075926)
54
+ address = location.first
55
+ assert_equal "4952-4958 Tobias Ave, Pico Rivera, CA 90660, USA", address.full_address
56
+ end
57
+
58
+ def test_should_raise_error_when_unknown_address
59
+ stub_response! :reverse_locate_602
60
+ assert_raise Google::Geo::UnknownAddressError do
61
+ @geo.locate(0, 0)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,23 @@
1
+ here = File.dirname __FILE__
2
+
3
+ ["vendor/mocha-0.4.0/lib", "lib"].each do |path|
4
+ p = "#{here}/../#{path}"
5
+ $:.unshift p unless $:.include? p
6
+ end
7
+
8
+ require "test/unit"
9
+ require "mocha"
10
+ require "google/geo"
11
+
12
+ begin; require "rubygems"; require "redgreen"; rescue LoadError; end
13
+
14
+ class Test::Unit::TestCase
15
+ def response(filename)
16
+ File.open "#{File.dirname __FILE__}/fixtures/#{filename}.xml"
17
+ end
18
+
19
+ def stub_response!(name)
20
+ Google::Geo::Response.any_instance.
21
+ expects(:open).returns(response(name))
22
+ end
23
+ end
metadata CHANGED
@@ -1,50 +1,75 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-geo
3
3
  version: !ruby/object:Gem::Version
4
- version: "2.1"
4
+ version: "2.3"
5
5
  platform: ruby
6
6
  authors:
7
- - |
8
-
9
-
7
+ - Seth Thomas Rasmussen
10
8
  autorequire:
11
9
  bindir: bin
12
10
  cert_chain: []
13
11
 
14
- date: 2008-02-11 00:00:00 -08:00
12
+ date: 2009-11-19 00:00:00 -05:00
15
13
  default_executable:
16
14
  dependencies: []
17
15
 
18
- description:
19
- email:
16
+ description: |
17
+ A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
18
+
19
+ email: sethrasmussen@gmail.com
20
20
  executables: []
21
21
 
22
22
  extensions: []
23
23
 
24
24
  extra_rdoc_files:
25
- - README
26
25
  - CHANGELOG
26
+ - LICENSE
27
+ - README.textile
28
+ - lib/google/geo.rb
29
+ - lib/google/geo/address.rb
30
+ - lib/google/geo/address/street_view.rb
31
+ - lib/google/geo/params.rb
32
+ - lib/google/geo/parser.rb
33
+ - lib/google/geo/response.rb
27
34
  files:
28
- - lib/google
35
+ - CHANGELOG
36
+ - LICENSE
37
+ - Manifest
38
+ - README.textile
39
+ - Rakefile
40
+ - google-geo.gemspec
29
41
  - lib/google/geo.rb
30
- - test/fixtures
42
+ - lib/google/geo/address.rb
43
+ - lib/google/geo/address/street_view.rb
44
+ - lib/google/geo/params.rb
45
+ - lib/google/geo/parser.rb
46
+ - lib/google/geo/response.rb
47
+ - script/test_street_view.rb
31
48
  - test/fixtures/invalid_map_key.xml
32
49
  - test/fixtures/missing_address.xml
50
+ - test/fixtures/reverse_locate_602.xml
51
+ - test/fixtures/reverse_locate_success.xml
33
52
  - test/fixtures/server_error.xml
53
+ - test/fixtures/streetview_success.xml
34
54
  - test/fixtures/success.xml
55
+ - test/fixtures/success_english.xml
56
+ - test/fixtures/success_german.xml
35
57
  - test/fixtures/success_with_multiple_addresses.xml
36
58
  - test/fixtures/too_many_queries.xml
37
59
  - test/fixtures/unavailable_address.xml
38
60
  - test/fixtures/unknown_address.xml
39
61
  - test/geo_test.rb
40
- - vendor/mocha-0.4.0
62
+ - test/reverse_locate_test.rb
63
+ - test/test_helper.rb
41
64
  - vendor/mocha-0.4.0/COPYING
42
- - vendor/mocha-0.4.0/examples
65
+ - vendor/mocha-0.4.0/MIT-LICENSE
66
+ - vendor/mocha-0.4.0/README
67
+ - vendor/mocha-0.4.0/RELEASE
68
+ - vendor/mocha-0.4.0/Rakefile
43
69
  - vendor/mocha-0.4.0/examples/misc.rb
44
70
  - vendor/mocha-0.4.0/examples/mocha.rb
45
71
  - vendor/mocha-0.4.0/examples/stubba.rb
46
- - vendor/mocha-0.4.0/lib
47
- - vendor/mocha-0.4.0/lib/mocha
72
+ - vendor/mocha-0.4.0/lib/mocha.rb
48
73
  - vendor/mocha-0.4.0/lib/mocha/any_instance_method.rb
49
74
  - vendor/mocha-0.4.0/lib/mocha/auto_verify.rb
50
75
  - vendor/mocha-0.4.0/lib/mocha/central.rb
@@ -62,19 +87,12 @@ files:
62
87
  - vendor/mocha-0.4.0/lib/mocha/setup_and_teardown.rb
63
88
  - vendor/mocha-0.4.0/lib/mocha/standalone.rb
64
89
  - vendor/mocha-0.4.0/lib/mocha/test_case_adapter.rb
65
- - vendor/mocha-0.4.0/lib/mocha.rb
66
90
  - vendor/mocha-0.4.0/lib/mocha_standalone.rb
67
91
  - vendor/mocha-0.4.0/lib/stubba.rb
68
- - vendor/mocha-0.4.0/MIT-LICENSE
69
- - vendor/mocha-0.4.0/Rakefile
70
- - vendor/mocha-0.4.0/README
71
- - vendor/mocha-0.4.0/RELEASE
72
- - vendor/mocha-0.4.0/test
73
92
  - vendor/mocha-0.4.0/test/active_record_test_case.rb
74
93
  - vendor/mocha-0.4.0/test/all_tests.rb
75
94
  - vendor/mocha-0.4.0/test/execution_point.rb
76
95
  - vendor/mocha-0.4.0/test/method_definer.rb
77
- - vendor/mocha-0.4.0/test/mocha
78
96
  - vendor/mocha-0.4.0/test/mocha/any_instance_method_test.rb
79
97
  - vendor/mocha-0.4.0/test/mocha/auto_verify_test.rb
80
98
  - vendor/mocha-0.4.0/test/mocha/central_test.rb
@@ -95,13 +113,18 @@ files:
95
113
  - vendor/mocha-0.4.0/test/stubba_integration_test.rb
96
114
  - vendor/mocha-0.4.0/test/stubba_test_result_integration_test.rb
97
115
  - vendor/mocha-0.4.0/test/test_helper.rb
98
- - README
99
- - CHANGELOG
100
116
  has_rdoc: true
101
- homepage:
102
- post_install_message:
103
- rdoc_options: []
117
+ homepage: http://github.com/greatseth/google-geo
118
+ licenses: []
104
119
 
120
+ post_install_message:
121
+ rdoc_options:
122
+ - --line-numbers
123
+ - --inline-source
124
+ - --title
125
+ - Google-geo
126
+ - --main
127
+ - README.textile
105
128
  require_paths:
106
129
  - lib
107
130
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -114,14 +137,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
137
  requirements:
115
138
  - - ">="
116
139
  - !ruby/object:Gem::Version
117
- version: "0"
140
+ version: "1.2"
118
141
  version:
119
142
  requirements: []
120
143
 
121
- rubyforge_project:
122
- rubygems_version: 1.0.1
144
+ rubyforge_project: google-geo
145
+ rubygems_version: 1.3.5
123
146
  signing_key:
124
- specification_version: 2
147
+ specification_version: 3
125
148
  summary: A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
126
149
  test_files:
127
150
  - test/geo_test.rb
151
+ - test/reverse_locate_test.rb
152
+ - test/test_helper.rb
data/README DELETED
@@ -1,35 +0,0 @@
1
- = Google::Geo
2
-
3
- A simple, elegant library for getting geocoding information from Google Maps. Very much inspired by the google-geocode gem, but completely dependency free!
4
-
5
- == Examples
6
-
7
- geo = Google::Geo.new API_KEY
8
-
9
- addresses = geo.locate '1600 Amphitheatre Parkway, Mountain View, CA'
10
-
11
- addresses.size # 1, :locate always returns an Array
12
-
13
- address = addresses.first
14
-
15
- address.country # 'US'
16
- address.city # 'Mountain View'
17
- address.full_address # '1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA'
18
-
19
- address.query # '1600 Amphitheatre Parkway, Mountain View, CA'
20
- address.accuracy # 8
21
-
22
- In the case of sufficiently vague queries, Google::Geo will return more than one:
23
-
24
- addresses = geo.locate 'hell'
25
-
26
- addresses.size # 2
27
- addresses.map { |a| a.state } # ['PA', 'NC']
28
-
29
- == Contributors
30
-
31
- Seth Thomas Rasmussen - http://sethrasmussen.com - sethrasmussen@gmail.com
32
-
33
- == License
34
-
35
- See LICENSE file.