geocoder_plus 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Fajar A B
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,26 @@
1
+ = geocoder_plus
2
+
3
+ This gem has two additional geocoders for geokit gem, Yahoo! PlaceFinder and Google V3.
4
+ Google V3 code is taken from https://github.com/tello/google-v3-geocoder.
5
+
6
+ Example:
7
+
8
+ Geokit::Geocoders::YahooPlaceFinderGeocoder.geocode('701 First Avenue Sunnyvale, California 94089')
9
+ Geokit::Geocoders::GoogleV3Geocoder.geocode('701 First Avenue Sunnyvale, California 94089')
10
+
11
+
12
+ == Contributing to geocoder_plus
13
+
14
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
15
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
16
+ * Fork the project
17
+ * Start a feature/bugfix branch
18
+ * Commit and push until you are happy with your contribution
19
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
20
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
21
+
22
+ == Copyright
23
+
24
+ Copyright (c) 2011 Fajar A B. See LICENSE.txt for
25
+ further details.
26
+
@@ -0,0 +1,19 @@
1
+ = geocoder_plus
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to geocoder_plus
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Fajar A B. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,5 @@
1
+ require 'geokit'
2
+ require 'geokit/geocoders.rb'
3
+ require 'yajl'
4
+ require 'geocoders/yahoo_place_finder_geocoder'
5
+ require 'geocoders/google_v3_geocoder'
@@ -0,0 +1,123 @@
1
+ # this code is taken from https://github.com/tello/google-v3-geocoder
2
+
3
+ module Geokit
4
+ module Geocoders
5
+ class GoogleV3Geocoder < Geocoder
6
+ private
7
+
8
+ def self.do_geocode(address, options = {})
9
+ geo_url = self.get_url(address, options)
10
+ logger.debug "Making Geocode request to: #{geo_url}"
11
+ res = self.call_geocoder_service(geo_url)
12
+
13
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
14
+ json = res.body
15
+ logger.debug "Google V3 geocoding. Address: #{address}. Result: #{json}"
16
+ return self.convert_json_to_geoloc(json)
17
+ end
18
+
19
+ def self.get_url(address, options={})
20
+ bias = options[:bias] || ''
21
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
22
+ return "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(address_str)}&region=#{bias.to_s.downcase}"
23
+ end
24
+
25
+ def self.convert_json_to_geoloc(json)
26
+ begin
27
+ data = Yajl::Parser.parse(json)
28
+ rescue
29
+ logger.error "Could not parse JSON from Google: #{json}"
30
+ return GeoLoc.new
31
+ end
32
+
33
+ if data['status'] != "OK"
34
+ if data['status' ] == 'OVER_QUERY_LIMIT'
35
+ raise Geokit::TooManyQueriesError "Google returned OVER_QUERY_LIMIT: #{json}"
36
+ elsif data['status'] == 'ZERO_RESULTS'
37
+ logger.info "Found no results from google v3"
38
+ return GeoLoc.new
39
+ end
40
+ logger.error "Got an error from google, response: #{json}"
41
+ # Otherwise, we don't know what to do
42
+ return GeoLoc.new
43
+ end
44
+
45
+ begin
46
+ results = data['results']
47
+ geoloc = nil
48
+ results.each do |result|
49
+ extracted_geoloc = self.extract_location(result)
50
+ if geoloc.nil?
51
+ geoloc = extracted_geoloc
52
+ else
53
+ geoloc.all.push(extracted_geoloc)
54
+ end
55
+ end
56
+ rescue Exception => e
57
+ logger.error "Encountered unexpected exception during google geocoding: #{e.inspect}"
58
+ return GeoLoc.new
59
+ end
60
+
61
+ return geoloc
62
+ end
63
+
64
+ def self.extract_location(result)
65
+ res = GeoLoc.new
66
+ res.provider = 'google_v3'
67
+
68
+ res.lat = result['geometry']['location']['lat']
69
+ res.lng = result['geometry']['location']['lng']
70
+
71
+ res.full_address = result['formatted_address']
72
+
73
+ street_number = nil
74
+ street_name = nil
75
+
76
+ result['address_components'].each do |component|
77
+ types = component['types']
78
+
79
+ if types.include?('street_number')
80
+ street_number = component['long_name']
81
+ end
82
+
83
+ if types.include?('route')
84
+ street_name = component['long_name']
85
+ end
86
+
87
+ if types.include?('country')
88
+ res.country = component['long_name']
89
+ res.country_code = component['short_name']
90
+ end
91
+
92
+ if types.include?('administrative_area_level_1')
93
+ res.state = component['short_name']
94
+ end
95
+
96
+ if types.include?('postal_code')
97
+ res.zip = component['long_name']
98
+ end
99
+
100
+ if types.include?('locality')
101
+ res.city = component['long_name']
102
+ end
103
+
104
+ if types.include?('postal_code')
105
+ res.zip = component['long_name']
106
+ end
107
+
108
+ end
109
+ res.street_address = [street_number, street_name].reject{|x| x.nil?}.join(" ")
110
+
111
+ # Set the bounds from the viewport
112
+ bounds = result['geometry']['viewport']
113
+ res.suggested_bounds = Bounds.normalize(
114
+ [bounds['southwest']['lat'], bounds['southwest']['lng']],
115
+ [bounds['northeast']['lat'], bounds['northeast']['lng']]
116
+ )
117
+
118
+ res.success = true
119
+ return res
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,113 @@
1
+ module Geokit
2
+ module Geocoders
3
+ class YahooPlaceFinderGeocoder < Geocoder
4
+ private
5
+
6
+ def self.get_url(address, options={})
7
+ if (options[:reverse])
8
+ latlng=LatLng.normalize(address)
9
+ yql = "select * from geo.placefinder where text='#{latlng}' and gflags='R'"
10
+ else
11
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
12
+ yql = "select * from geo.placefinder where text='#{address}'"
13
+ end
14
+ return "http://query.yahooapis.com/v1/public/yql?q=#{Geokit::Inflector::url_escape(yql)}&format=json"
15
+ end
16
+
17
+ def self.do_reverse_geocode(latlng)
18
+ res = self.call_geocoder_service(self.get_url(latlng, :reverse => true))
19
+ logger.debug "Yahoo PlaceFinder reverse-geocoding. LL: #{latlng}. Result: #{res}"
20
+ return self.parse_body(Yajl::Parser.parse(res.body))
21
+ end
22
+
23
+ def self.do_geocode(address, options={})
24
+ address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
25
+ res = self.call_geocoder_service(self.get_url(address, options))
26
+ return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
27
+ logger.debug "Yahoo PlaceFinder geocoding. Address: #{address}. Result: #{res}"
28
+
29
+ return self.parse_body(Yajl::Parser.parse(res.body))
30
+ rescue
31
+ logger.info "Caught an error during Yahoo PlaceFinder geocoding call: "+$!
32
+ return GeoLoc.new
33
+ end
34
+
35
+ def self.parse_body(body)
36
+ count = body['query']['count']
37
+ if (count == 1)
38
+ return extract_place(body['query']['results']['Result'])
39
+ elsif (count > 1)
40
+ results = body['query']['results']['Result']
41
+ geoloc = nil
42
+ results.each do |r|
43
+ extracted_geoloc = extract_place(r)
44
+ if geoloc.nil?
45
+ # first time through, geoloc is still nil, so we make it the geoloc we just extracted
46
+ geoloc = extracted_geoloc
47
+ else
48
+ # second (and subsequent) iterations, we push additional
49
+ # geoloc onto "geoloc.all"
50
+ geoloc.all.push(extracted_geoloc)
51
+ end
52
+ end
53
+ return geoloc
54
+ else
55
+ return GeoLoc.new
56
+ end
57
+ end
58
+
59
+ def self.extract_place(result)
60
+ geoloc = GeoLoc.new
61
+
62
+ # basics
63
+ geoloc.lat = result['latitude']
64
+ geoloc.lng = result['longitude']
65
+ geoloc.country_code = result['countrycode']
66
+ geoloc.provider = 'Yahoo! PlaceFinder'
67
+
68
+ # extended -- false if not not available
69
+ geoloc.street_address = result['line1']
70
+ geoloc.city = result['city']
71
+ # geoloc.neighborhood = result['neighborhood']
72
+ # geoloc.county = result['county']
73
+ geoloc.zip = result['postal']
74
+ geoloc.country = result['country']
75
+ # geoloc.quality = result['quality']
76
+ # geoloc.woeid = result['woeid']
77
+ # geoloc.woetype = result['woetype']
78
+ if geoloc.is_us?
79
+ geoloc.state = result['statecode']
80
+ else
81
+ geoloc.state = result['state']
82
+ end
83
+ case result['quality'].to_i
84
+ when 9,10 then geoloc.precision = 'country'
85
+ when 19..30 then geoloc.precision = 'state'
86
+ when 39,40 then geoloc.precision = 'city'
87
+ when 49,50 then geoloc.precision = 'neighborhood'
88
+ when 59,60,64 then geoloc.precision = 'zip'
89
+ when 74,75 then geoloc.precision = 'zip+4'
90
+ when 70..72 then geoloc.precision = 'street'
91
+ when 80..87 then geoloc.precision = 'address'
92
+ when 62,63,90,99 then geoloc.precision = 'building'
93
+ else 'unknown'
94
+ end
95
+
96
+ geoloc.accuracy = %w{unknown country state state city zip zip+4 street address building}.index(geoloc.precision)
97
+ # geoloc.full_address = "#{geoloc.street_address}, #{result['line2']}, #{geoloc.country}" if (geoloc.street_address && result['line2'])
98
+
99
+ # google returns a set of suggested boundaries for the geocoded result
100
+ # if suggested_bounds = doc.elements['//LatLonBox']
101
+ # res.suggested_bounds = Bounds.normalize(
102
+ # [suggested_bounds.attributes['south'], suggested_bounds.attributes['west']],
103
+ # [suggested_bounds.attributes['north'], suggested_bounds.attributes['east']])
104
+ # end
105
+
106
+ geoloc.success = true
107
+
108
+ return geoloc
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+ require 'mocha'
13
+
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
16
+ require 'geocoder_plus'
17
+
18
+ class Test::Unit::TestCase
19
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestGeocoderPlus < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,280 @@
1
+ # this code is taken from https://github.com/tello/google-v3-geocoder
2
+
3
+ require 'helper'
4
+
5
+ class GoogleV3GeocoderTest < Test::Unit::TestCase
6
+ include Geokit
7
+
8
+ GOOD_JSON = <<-JSON
9
+ {
10
+ "status": "OK",
11
+ "results": [ {
12
+ "types": [ "street_address" ],
13
+ "formatted_address": "1288 E Hillsdale Blvd, Foster City, CA 94404, USA",
14
+ "address_components": [ {
15
+ "long_name": "1288",
16
+ "short_name": "1288",
17
+ "types": [ "street_number" ]
18
+ }, {
19
+ "long_name": "E Hillsdale Blvd",
20
+ "short_name": "E Hillsdale Blvd",
21
+ "types": [ "route" ]
22
+ }, {
23
+ "long_name": "Foster City",
24
+ "short_name": "Foster City",
25
+ "types": [ "locality", "political" ]
26
+ }, {
27
+ "long_name": "San Mateo",
28
+ "short_name": "San Mateo",
29
+ "types": [ "administrative_area_level_3", "political" ]
30
+ }, {
31
+ "long_name": "San Mateo",
32
+ "short_name": "San Mateo",
33
+ "types": [ "administrative_area_level_2", "political" ]
34
+ }, {
35
+ "long_name": "California",
36
+ "short_name": "CA",
37
+ "types": [ "administrative_area_level_1", "political" ]
38
+ }, {
39
+ "long_name": "United States",
40
+ "short_name": "US",
41
+ "types": [ "country", "political" ]
42
+ }, {
43
+ "long_name": "94404",
44
+ "short_name": "94404",
45
+ "types": [ "postal_code" ]
46
+ } ],
47
+ "geometry": {
48
+ "location": {
49
+ "lat": 37.5684570,
50
+ "lng": -122.2660670
51
+ },
52
+ "location_type": "ROOFTOP",
53
+ "viewport": {
54
+ "southwest": {
55
+ "lat": 37.5653094,
56
+ "lng": -122.2692146
57
+ },
58
+ "northeast": {
59
+ "lat": 37.5716046,
60
+ "lng": -122.2629194
61
+ }
62
+ }
63
+ }
64
+ } ]
65
+ }
66
+ JSON
67
+
68
+ def test_get_url_adds_bias_if_set
69
+ bias = 'thefreakingus'
70
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :get_url, 'address', :bias => bias
71
+ assert_match /&region=#{bias}/, result
72
+ end
73
+
74
+ def test_get_url_escapes_address
75
+ address = '123 hotel street'
76
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :get_url, address
77
+ assert_match /&address=#{Regexp.escape(Geokit::Inflector::url_escape(address))}/, result
78
+ end
79
+
80
+ def test_convert_json_to_geoloc_extracts_result_from_json
81
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :convert_json_to_geoloc, GOOD_JSON
82
+ assert result.success
83
+ assert_equal 1, result.all.size
84
+ assert_equal '1288 E Hillsdale Blvd, Foster City, CA 94404, USA', result.full_address
85
+ end
86
+
87
+ def test_convert_json_to_geoloc_handles_empty_result_set
88
+ empty_json = '{"status": "ZERO_RESULTS","results": [ ]}'
89
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :convert_json_to_geoloc, empty_json
90
+ assert !result.success
91
+ assert_equal 1, result.all.size
92
+ assert_nil result.lat
93
+ assert_nil result.lng
94
+ end
95
+
96
+ def test_convert_json_to_geoloc_calls_extract_location
97
+ expected_geoloc = GeoLoc.new
98
+ expected_geoloc.city = "SOME City"
99
+ Geokit::Geocoders::GoogleV3Geocoder.expects(:extract_location).returns expected_geoloc
100
+
101
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :convert_json_to_geoloc, GOOD_JSON
102
+ assert_equal result, expected_geoloc
103
+ end
104
+
105
+ def test_convert_json_to_handles_multiple_results
106
+ address1 = 'add1'
107
+ address2 = 'add2'
108
+
109
+ input_data = {
110
+ "status" => "OK",
111
+ "results" =>
112
+ [
113
+ {
114
+ "types" => [ "street_address" ],
115
+ "formatted_address" => address1,
116
+ "address_components" => [],
117
+ "geometry" => {
118
+ "location"=> {
119
+ "lat"=> 35.58032,
120
+ "lng"=> -122.2660670
121
+ },
122
+ "location_type"=> "ROOFTOP",
123
+ "viewport"=> {
124
+ "southwest"=> {
125
+ "lat"=> 37.5653094,
126
+ "lng"=> -122.2692146,
127
+ },
128
+ "northeast"=> {
129
+ "lat"=> 37.5716046,
130
+ "lng"=> -122.2629194
131
+ }
132
+ },
133
+ },
134
+ },
135
+ {
136
+ "types" => [ "street_address" ],
137
+ "formatted_address" => address2,
138
+ "address_components" => [],
139
+ "geometry" => {
140
+ "location"=> {
141
+ "lat"=> 35.58032,
142
+ "lng"=> -122.2660670
143
+ },
144
+ "location_type"=> "ROOFTOP",
145
+ "viewport"=> {
146
+ "southwest"=> {
147
+ "lat"=> 37.5653094,
148
+ "lng"=> -122.2692146,
149
+ },
150
+ "northeast"=> {
151
+ "lat"=> 37.5716046,
152
+ "lng"=> -122.2629194
153
+ }
154
+ },
155
+ },
156
+ }
157
+ ]
158
+ }
159
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :convert_json_to_geoloc, Yajl::Encoder.encode(input_data)
160
+ assert result.success
161
+ assert_equal 2, result.all.size
162
+ assert_equal address1, result.all[0].full_address
163
+ assert_equal address2, result.all[1].full_address
164
+ end
165
+
166
+ def test_extract_location_extracts_result_from_json
167
+ data = Yajl::Parser.parse(GOOD_JSON)['results'][0]
168
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :extract_location, data
169
+ assert_equal 'Foster City', result.city
170
+ assert_equal 'CA', result.state
171
+ assert_equal '94404', result.zip
172
+ assert_equal 'United States', result.country
173
+ assert_equal 'US', result.country_code
174
+ assert_equal '1288 E Hillsdale Blvd', result.street_address
175
+ assert_equal '1288 E Hillsdale Blvd, Foster City, CA 94404, USA', result.full_address
176
+ assert_equal 37.5653094, result.suggested_bounds.sw.lat
177
+ assert_equal -122.2692146, result.suggested_bounds.sw.lng
178
+ assert_equal 37.5716046, result.suggested_bounds.ne.lat
179
+ assert_equal -122.2629194, result.suggested_bounds.ne.lng
180
+ end
181
+
182
+ def test_extract_joins_street_address_with_no_number
183
+ route_name = 'Foo'
184
+ data =
185
+ {
186
+ "types" => [ "street_address" ],
187
+ "formatted_address" => 'address1',
188
+ "address_components" => [
189
+ {'types' => ['route'], 'long_name' => route_name, 'short_name' => route_name}
190
+ ],
191
+ "geometry" => {
192
+ "location"=> {
193
+ "lat"=> 35.58032,
194
+ "lng"=> -122.2660670
195
+ },
196
+ "location_type"=> "ROOFTOP",
197
+ "viewport"=> {
198
+ "southwest"=> {
199
+ "lat"=> 37.5653094,
200
+ "lng"=> -122.2692146,
201
+ },
202
+ "northeast"=> {
203
+ "lat"=> 37.5716046,
204
+ "lng"=> -122.2629194
205
+ }
206
+ },
207
+ },
208
+ }
209
+
210
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :extract_location, data
211
+ assert_equal route_name, result.street_address
212
+ end
213
+
214
+ def test_extract_joins_street_address_with_no_route
215
+ number = '358'
216
+ data =
217
+ {
218
+ "types" => [ "street_address" ],
219
+ "formatted_address" => 'address1',
220
+ "address_components" => [
221
+ {'types' => ['street_number'], 'long_name' => number, 'short_name' => number},
222
+ ],
223
+ "geometry" => {
224
+ "location"=> {
225
+ "lat"=> 35.58032,
226
+ "lng"=> -122.2660670
227
+ },
228
+ "location_type"=> "ROOFTOP",
229
+ "viewport"=> {
230
+ "southwest"=> {
231
+ "lat"=> 37.5653094,
232
+ "lng"=> -122.2692146,
233
+ },
234
+ "northeast"=> {
235
+ "lat"=> 37.5716046,
236
+ "lng"=> -122.2629194
237
+ }
238
+ },
239
+ },
240
+ }
241
+
242
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :extract_location, data
243
+ assert_equal number, result.street_address
244
+ end
245
+
246
+ def test_extract_joins_street_address_with_number_and_route
247
+ route_name = 'Foo'
248
+ number = '3854'
249
+ data =
250
+ {
251
+ "types" => [ "street_address" ],
252
+ "formatted_address" => 'address1',
253
+ "address_components" => [
254
+ {'types' => ['route'], 'long_name' => route_name, 'short_name' => route_name},
255
+ {'types' => ['street_number'], 'long_name' => number, 'short_name' => number}
256
+ ],
257
+ "geometry" => {
258
+ "location"=> {
259
+ "lat"=> 35.58032,
260
+ "lng"=> -122.2660670
261
+ },
262
+ "location_type"=> "ROOFTOP",
263
+ "viewport"=> {
264
+ "southwest"=> {
265
+ "lat"=> 37.5653094,
266
+ "lng"=> -122.2692146,
267
+ },
268
+ "northeast"=> {
269
+ "lat"=> 37.5716046,
270
+ "lng"=> -122.2629194
271
+ }
272
+ },
273
+ },
274
+ }
275
+
276
+ result = Geokit::Geocoders::GoogleV3Geocoder.send :extract_location, data
277
+ assert_equal number + ' ' + route_name, result.street_address
278
+ end
279
+
280
+ end
@@ -0,0 +1,139 @@
1
+ require 'helper'
2
+
3
+ class TestYahooPlaceFinderGeocoder < Test::Unit::TestCase
4
+
5
+ # default is true
6
+ MOCK = false
7
+
8
+ US_FULL_ADDRESS=<<-EOF.strip
9
+ {"query":{"count":1,"created":"2011-04-03T01:20:47Z","lang":"en-US","results":{"Result":{"quality":"87","latitude":"37.792418","longitude":"-122.393913","offsetlat":"37.792332","offsetlon":"-122.394027","radius":"500","name":null,"line1":"100 Spear St","line2":"San Francisco, CA 94105-1578","line3":null,"line4":"United States","house":"100","street":"Spear St","xstreet":null,"unittype":null,"unit":null,"postal":"94105-1578","neighborhood":null,"city":"San Francisco","county":"San Francisco County","state":"California","country":"United States","countrycode":"US","statecode":"CA","countycode":null,"uzip":"94105","hash":"0FA06819B5F53E75","woeid":"12797156","woetype":"11"}}}}
10
+ EOF
11
+
12
+ US_CITY=<<-EOF.strip
13
+ {"query":{"count":1,"created":"2011-04-04T15:10:42Z","lang":"en-US","results":{"Result":{"quality":"40","latitude":"37.777125","longitude":"-122.419644","offsetlat":"37.777125","offsetlon":"-122.419644","radius":"10700","name":null,"line1":null,"line2":"San Francisco, CA","line3":null,"line4":"United States","house":null,"street":null,"xstreet":null,"unittype":null,"unit":null,"postal":null,"neighborhood":null,"city":"San Francisco","county":"San Francisco County","state":"California","country":"United States","countrycode":"US","statecode":"CA","countycode":null,"uzip":"94102","hash":null,"woeid":"2487956","woetype":"7"}}}}
14
+ EOF
15
+
16
+ context "given a US full address" do
17
+ setup do
18
+ full_address = '100 Spear St, San Francisco, CA, 94105-1522, US'
19
+ if MOCK
20
+ response = Typhoeus::Response.new(@success_response.merge(:body => US_FULL_ADDRESS))
21
+ Geokit::Geocoders::YahooPlaceFinderGeocoder.expects(:make_request).with('get', :params => {:q => "select * from geo.placefinder where text='#{full_address}'", :format => 'json'}).returns(response)
22
+ end
23
+ @pf = Geokit::Geocoders::YahooPlaceFinderGeocoder.geocode(full_address)
24
+ end
25
+
26
+ should "return correct geo location" do
27
+ do_full_address_assertions(@pf)
28
+ assert @pf.is_us?
29
+ end
30
+
31
+ should "have 'address' accuracy" do
32
+ assert_equal 'address', @pf.precision
33
+ end
34
+ end
35
+
36
+ context "given a US city" do
37
+ setup do
38
+ city = 'San Francisco, CA'
39
+ if MOCK
40
+ response = Typhoeus::Response.new(@success_response.merge(:body => US_CITY))
41
+ Geokit::Geocoders::YahooPlaceFinderGeocoder.expects(:make_request).with('get', :params => {:q => "select * from geo.placefinder where text='#{city}'", :format => 'json'}).returns(response)
42
+ end
43
+ @pf = Geokit::Geocoders::YahooPlaceFinderGeocoder.geocode(city)
44
+ end
45
+
46
+ should "return correct geo location" do
47
+ do_city_assertions(@pf)
48
+ assert @pf.is_us?
49
+ end
50
+
51
+ should "have 'address' accuracy" do
52
+ assert_equal 'city', @pf.precision
53
+ end
54
+ end
55
+
56
+ context "given a non-US street" do
57
+ setup do
58
+ full_address = 'Jalan Gandaria Tengah, Jakarta 12140, Indonesia'
59
+ if MOCK
60
+ response = Typhoeus::Response.new(@success_response.merge(:body => US_FULL_ADDRESS))
61
+ Geokit::Geocoders::YahooPlaceFinderGeocoder.expects(:make_request).with('get', :params => {:q => "select * from geo.placefinder where text='#{full_address}'", :format => 'json'}).returns(response)
62
+ end
63
+ @pf = Geokit::Geocoders::YahooPlaceFinderGeocoder.geocode(full_address)
64
+ end
65
+
66
+ should "return correct geo location" do
67
+ do_non_us_street_assertions(@pf)
68
+ end
69
+
70
+ should "have 'address' accuracy" do
71
+ assert_equal 'street', @pf.precision
72
+ end
73
+ end
74
+
75
+ context "given a non-US city" do
76
+ setup do
77
+ city = 'Jakarta, Indonesia'
78
+ if MOCK
79
+ response = Typhoeus::Response.new(@success_response.merge(:body => US_CITY))
80
+ Geokit::Geocoders::YahooPlaceFinderGeocoder.expects(:make_request).with('get', :params => {:q => "select * from geo.placefinder where text='#{city}'", :format => 'json'}).returns(response)
81
+ end
82
+ @pf = Geokit::Geocoders::YahooPlaceFinderGeocoder.geocode(city)
83
+ end
84
+
85
+ should "return correct geo location" do
86
+ do_non_us_city_assertions(@pf)
87
+ end
88
+
89
+ should "have 'address' accuracy" do
90
+ assert_equal 'city', @pf.precision
91
+ end
92
+ end
93
+
94
+
95
+
96
+
97
+
98
+ private
99
+
100
+ # next two methods do the assertions for both address-level and city-level lookups
101
+ def do_full_address_assertions(resp)
102
+ assert_equal "CA", resp.state
103
+ assert_equal "San Francisco", resp.city
104
+ assert_equal "37.792418,-122.393913", resp.ll
105
+ assert resp.is_us?
106
+ assert_equal "100 Spear St, San Francisco, CA, 94105-1578, US", resp.full_address
107
+ assert_equal "Yahoo! PlaceFinder", resp.provider
108
+ end
109
+
110
+ def do_city_assertions(resp)
111
+ assert_equal "CA", resp.state
112
+ assert_equal "San Francisco", resp.city
113
+ assert_equal "37.777125,-122.419644", resp.ll
114
+ assert resp.is_us?
115
+ assert_equal "San Francisco, CA, US", resp.full_address
116
+ assert_nil resp.street_address
117
+ assert_equal "Yahoo! PlaceFinder", resp.provider
118
+ end
119
+
120
+ def do_non_us_street_assertions(resp)
121
+ assert_equal "D K I Jakarta", resp.state
122
+ assert_equal "Kebayoran Baru", resp.city
123
+ assert_equal "-6.246406,106.789707", resp.ll
124
+ assert_equal false, resp.is_us?
125
+ assert_equal "Jalan Gandaria Tengah 3, Kebayoran Baru, D K I Jakarta, 12140, ID", resp.full_address
126
+ assert_equal "Yahoo! PlaceFinder", resp.provider
127
+ end
128
+
129
+ def do_non_us_city_assertions(resp)
130
+ assert_equal "DKI Jakarta", resp.state
131
+ assert_equal "Jakarta", resp.city
132
+ assert_equal "-6.17144,106.82782", resp.ll
133
+ assert_equal false, resp.is_us?
134
+ assert_equal "Jakarta, DKI Jakarta, ID", resp.full_address
135
+ assert_nil resp.street_address
136
+ assert_equal "Yahoo! PlaceFinder", resp.provider
137
+ end
138
+
139
+ end
metadata ADDED
@@ -0,0 +1,246 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geocoder_plus
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Fajar A B
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-06 00:00:00 +07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 1
30
+ - 5
31
+ - 0
32
+ version: 1.5.0
33
+ version_requirements: *id001
34
+ name: geokit
35
+ prerelease: false
36
+ type: :runtime
37
+ - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 59
44
+ segments:
45
+ - 0
46
+ - 8
47
+ - 2
48
+ version: 0.8.2
49
+ version_requirements: *id002
50
+ name: yajl-ruby
51
+ prerelease: false
52
+ type: :runtime
53
+ - !ruby/object:Gem::Dependency
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ version_requirements: *id003
64
+ name: shoulda
65
+ prerelease: false
66
+ type: :development
67
+ - !ruby/object:Gem::Dependency
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ version_requirements: *id004
78
+ name: mocha
79
+ prerelease: false
80
+ type: :development
81
+ - !ruby/object:Gem::Dependency
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 23
88
+ segments:
89
+ - 1
90
+ - 0
91
+ - 0
92
+ version: 1.0.0
93
+ version_requirements: *id005
94
+ name: bundler
95
+ prerelease: false
96
+ type: :development
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ hash: 7
104
+ segments:
105
+ - 1
106
+ - 5
107
+ - 2
108
+ version: 1.5.2
109
+ version_requirements: *id006
110
+ name: jeweler
111
+ prerelease: false
112
+ type: :development
113
+ - !ruby/object:Gem::Dependency
114
+ requirement: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ version_requirements: *id007
124
+ name: rcov
125
+ prerelease: false
126
+ type: :development
127
+ - !ruby/object:Gem::Dependency
128
+ requirement: &id008 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ hash: 3
134
+ segments:
135
+ - 1
136
+ - 5
137
+ - 0
138
+ version: 1.5.0
139
+ version_requirements: *id008
140
+ name: geokit
141
+ prerelease: false
142
+ type: :runtime
143
+ - !ruby/object:Gem::Dependency
144
+ requirement: &id009 !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ hash: 59
150
+ segments:
151
+ - 0
152
+ - 8
153
+ - 2
154
+ version: 0.8.2
155
+ version_requirements: *id009
156
+ name: yajl-ruby
157
+ prerelease: false
158
+ type: :runtime
159
+ - !ruby/object:Gem::Dependency
160
+ requirement: &id010 !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ">"
164
+ - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
167
+ - 0
168
+ version: "0"
169
+ version_requirements: *id010
170
+ name: shoulda
171
+ prerelease: false
172
+ type: :development
173
+ - !ruby/object:Gem::Dependency
174
+ requirement: &id011 !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ">"
178
+ - !ruby/object:Gem::Version
179
+ hash: 3
180
+ segments:
181
+ - 0
182
+ version: "0"
183
+ version_requirements: *id011
184
+ name: mocha
185
+ prerelease: false
186
+ type: :development
187
+ description: This gem consists two additional geocoders for geokit, Yahoo! PlaceFinder and Google V3
188
+ email: fajar.ab@gmail.com
189
+ executables: []
190
+
191
+ extensions: []
192
+
193
+ extra_rdoc_files:
194
+ - LICENSE.txt
195
+ - README
196
+ - README.rdoc
197
+ files:
198
+ - lib/geocoder_plus.rb
199
+ - lib/geocoders/google_v3_geocoder.rb
200
+ - lib/geocoders/yahoo_place_finder_geocoder.rb
201
+ - LICENSE.txt
202
+ - README
203
+ - README.rdoc
204
+ - test/helper.rb
205
+ - test/test_geocoder_plus.rb
206
+ - test/test_google_v3_geocoder.rb
207
+ - test/test_yahoo_place_finder_geocoder.rb
208
+ has_rdoc: true
209
+ homepage: http://github.com/fajarb/geocoder_plus
210
+ licenses:
211
+ - MIT
212
+ post_install_message:
213
+ rdoc_options: []
214
+
215
+ require_paths:
216
+ - lib
217
+ required_ruby_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ hash: 3
223
+ segments:
224
+ - 0
225
+ version: "0"
226
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
+ none: false
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ hash: 3
232
+ segments:
233
+ - 0
234
+ version: "0"
235
+ requirements: []
236
+
237
+ rubyforge_project:
238
+ rubygems_version: 1.6.1
239
+ signing_key:
240
+ specification_version: 3
241
+ summary: Additional geocoders for geokit gem
242
+ test_files:
243
+ - test/helper.rb
244
+ - test/test_geocoder_plus.rb
245
+ - test/test_google_v3_geocoder.rb
246
+ - test/test_yahoo_place_finder_geocoder.rb