ggeocode 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +16 -0
  2. data/Rakefile +364 -0
  3. data/lib/ggeocode.rb +166 -0
  4. metadata +69 -0
data/README ADDED
@@ -0,0 +1,16 @@
1
+ NAME
2
+ ggeocode
3
+
4
+ SYNOPSIS
5
+ require 'ggeocode'
6
+
7
+ hash = GGeocode.geocode('boulder, co')
8
+ hash = GGeocode.rgeocode('40.0149856,-105.2705456')
9
+
10
+ INSTALL
11
+ gem install ggeocode
12
+
13
+ DESCRIPTION
14
+ a simple interface to google's new geocoding api
15
+
16
+ see http://code.google.com/apis/maps/documentation/geocoding/
data/Rakefile ADDED
@@ -0,0 +1,364 @@
1
+ This.rubyforge_project = 'codeforpeople'
2
+ This.author = "Ara T. Howard"
3
+ This.email = "ara.t.howard@gmail.com"
4
+ This.homepage = "http://github.com/ahoward/#{ This.lib }"
5
+
6
+
7
+ task :default do
8
+ puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
9
+ end
10
+
11
+ task :test do
12
+ run_tests!
13
+ end
14
+
15
+ namespace :test do
16
+ task(:unit){ run_tests!(:unit) }
17
+ task(:functional){ run_tests!(:functional) }
18
+ task(:integration){ run_tests!(:integration) }
19
+ end
20
+
21
+ def run_tests!(which = nil)
22
+ which ||= '**'
23
+ test_dir = File.join(This.dir, "test")
24
+ test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
25
+ test_rbs = Dir.glob(test_glob).sort
26
+
27
+ div = ('=' * 119)
28
+ line = ('-' * 119)
29
+ helper = "-r ./test/helper.rb" if test(?e, "./test/helper.rb")
30
+
31
+ test_rbs.each_with_index do |test_rb, index|
32
+ testno = index + 1
33
+ command = "#{ This.ruby } -I ./lib -I ./test/lib #{ helper } #{ test_rb }"
34
+
35
+ puts
36
+ say(div, :color => :cyan, :bold => true)
37
+ say("@#{ testno } => ", :bold => true, :method => :print)
38
+ say(command, :color => :cyan, :bold => true)
39
+ say(line, :color => :cyan, :bold => true)
40
+
41
+ system(command)
42
+
43
+ say(line, :color => :cyan, :bold => true)
44
+
45
+ status = $?.exitstatus
46
+
47
+ if status.zero?
48
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
49
+ say("SUCCESS", :color => :green, :bold => true)
50
+ else
51
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
52
+ say("FAILURE", :color => :red, :bold => true)
53
+ end
54
+ say(line, :color => :cyan, :bold => true)
55
+
56
+ exit(status) unless status.zero?
57
+ end
58
+ end
59
+
60
+
61
+ task :gemspec do
62
+ ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem'
63
+ ignore_directories = %w[ pkg ]
64
+ ignore_files = %w[ test/log ]
65
+
66
+ shiteless =
67
+ lambda do |list|
68
+ list.delete_if do |entry|
69
+ next unless test(?e, entry)
70
+ extension = File.basename(entry).split(%r/[.]/).last
71
+ ignore_extensions.any?{|ext| ext === extension}
72
+ end
73
+ list.delete_if do |entry|
74
+ next unless test(?d, entry)
75
+ dirname = File.expand_path(entry)
76
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
77
+ end
78
+ list.delete_if do |entry|
79
+ next unless test(?f, entry)
80
+ filename = File.expand_path(entry)
81
+ ignore_files.any?{|file| File.expand_path(file) == filename}
82
+ end
83
+ end
84
+
85
+ lib = This.lib
86
+ object = This.object
87
+ version = This.version
88
+ files = shiteless[Dir::glob("**/**")]
89
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
90
+ has_rdoc = true #File.exist?('doc')
91
+ test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
92
+ summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
93
+ description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
94
+
95
+ if This.extensions.nil?
96
+ This.extensions = []
97
+ extensions = This.extensions
98
+ %w( Makefile configure extconf.rb ).each do |ext|
99
+ extensions << ext if File.exists?(ext)
100
+ end
101
+ end
102
+ extensions = [extensions].flatten.compact
103
+
104
+ template =
105
+ if test(?e, 'gemspec.erb')
106
+ Template{ IO.read('gemspec.erb') }
107
+ else
108
+ Template {
109
+ <<-__
110
+ ## #{ lib }.gemspec
111
+ #
112
+
113
+ Gem::Specification::new do |spec|
114
+ spec.name = #{ lib.inspect }
115
+ spec.version = #{ version.inspect }
116
+ spec.platform = Gem::Platform::RUBY
117
+ spec.summary = #{ lib.inspect }
118
+ spec.description = #{ description.inspect }
119
+
120
+ spec.files = #{ files.inspect }
121
+ spec.executables = #{ executables.inspect }
122
+
123
+ spec.require_path = "lib"
124
+
125
+ spec.has_rdoc = #{ has_rdoc.inspect }
126
+ spec.test_files = #{ test_files.inspect }
127
+
128
+ # spec.add_dependency 'lib', '>= version'
129
+
130
+ spec.extensions.push(*#{ extensions.inspect })
131
+
132
+ spec.rubyforge_project = #{ This.rubyforge_project.inspect }
133
+ spec.author = #{ This.author.inspect }
134
+ spec.email = #{ This.email.inspect }
135
+ spec.homepage = #{ This.homepage.inspect }
136
+ end
137
+ __
138
+ }
139
+ end
140
+
141
+ Fu.mkdir_p(This.pkgdir)
142
+ This.gemspec = File.join(This.dir, "#{ This.lib }.gemspec") #File.join(This.pkgdir, "gemspec.rb")
143
+ open("#{ This.gemspec }", "w"){|fd| fd.puts(template)}
144
+ end
145
+
146
+ task :gem => [:clean, :gemspec] do
147
+ Fu.mkdir_p(This.pkgdir)
148
+ before = Dir['*.gem']
149
+ cmd = "gem build #{ This.gemspec }"
150
+ `#{ cmd }`
151
+ after = Dir['*.gem']
152
+ gem = ((after - before).first || after.first) or abort('no gem!')
153
+ Fu.mv gem, This.pkgdir
154
+ This.gem = File.basename(gem)
155
+ end
156
+
157
+ task :readme do
158
+ samples = ''
159
+ prompt = '~ > '
160
+ lib = This.lib
161
+ version = This.version
162
+
163
+ Dir['sample*/*'].sort.each do |sample|
164
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
165
+
166
+ cmd = "cat #{ sample }"
167
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
168
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
169
+
170
+ cmd = "ruby #{ sample }"
171
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
172
+
173
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
174
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
175
+ end
176
+
177
+ template =
178
+ if test(?e, 'readme.erb')
179
+ Template{ IO.read('readme.erb') }
180
+ else
181
+ Template {
182
+ <<-__
183
+ NAME
184
+ #{ lib }
185
+
186
+ DESCRIPTION
187
+
188
+ INSTALL
189
+ gem install #{ lib }
190
+
191
+ SAMPLES
192
+ #{ samples }
193
+ __
194
+ }
195
+ end
196
+
197
+ open("README", "w"){|fd| fd.puts template}
198
+ end
199
+
200
+
201
+ task :clean do
202
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
203
+ end
204
+
205
+
206
+ task :release => [:clean, :gemspec, :gem] do
207
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
208
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
209
+ raise "no gems?" if gems.size < 1
210
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.pkgdir }/#{ This.gem }"
211
+ puts cmd
212
+ system cmd
213
+ cmd = "gem push #{ This.pkgdir }/#{ This.gem }"
214
+ puts cmd
215
+ system cmd
216
+ end
217
+
218
+
219
+
220
+
221
+
222
+ BEGIN {
223
+ # support for this rakefile
224
+ #
225
+ $VERBOSE = nil
226
+
227
+ require 'ostruct'
228
+ require 'erb'
229
+ require 'fileutils'
230
+ require 'rbconfig'
231
+
232
+ # fu shortcut
233
+ #
234
+ Fu = FileUtils
235
+
236
+ # cache a bunch of stuff about this rakefile/environment
237
+ #
238
+ This = OpenStruct.new
239
+
240
+ This.file = File.expand_path(__FILE__)
241
+ This.dir = File.dirname(This.file)
242
+ This.pkgdir = File.join(This.dir, 'pkg')
243
+
244
+ # grok lib
245
+ #
246
+ lib = ENV['LIB']
247
+ unless lib
248
+ lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
249
+ end
250
+ This.lib = lib
251
+
252
+ # grok version
253
+ #
254
+ version = ENV['VERSION']
255
+ unless version
256
+ require "./lib/#{ This.lib }"
257
+ This.name = lib.capitalize
258
+ This.object = eval(This.name)
259
+ version = This.object.send(:version)
260
+ end
261
+ This.version = version
262
+
263
+ # we need to know the name of the lib an it's version
264
+ #
265
+ abort('no lib') unless This.lib
266
+ abort('no version') unless This.version
267
+
268
+ # discover full path to this ruby executable
269
+ #
270
+ c = Config::CONFIG
271
+ bindir = c["bindir"] || c['BINDIR']
272
+ ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
273
+ ruby_ext = c['EXEEXT'] || ''
274
+ ruby = File.join(bindir, (ruby_install_name + ruby_ext))
275
+ This.ruby = ruby
276
+
277
+ # some utils
278
+ #
279
+ module Util
280
+ def indent(s, n = 2)
281
+ s = unindent(s)
282
+ ws = ' ' * n
283
+ s.gsub(%r/^/, ws)
284
+ end
285
+
286
+ def unindent(s)
287
+ indent = nil
288
+ s.each_line do |line|
289
+ next if line =~ %r/^\s*$/
290
+ indent = line[%r/^\s*/] and break
291
+ end
292
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
293
+ end
294
+ extend self
295
+ end
296
+
297
+ # template support
298
+ #
299
+ class Template
300
+ def initialize(&block)
301
+ @block = block.binding
302
+ @template = block.call.to_s
303
+ end
304
+ def expand(b=nil)
305
+ ERB.new(Util.unindent(@template)).result(b||@block)
306
+ end
307
+ alias_method 'to_s', 'expand'
308
+ end
309
+ def Template(*args, &block) Template.new(*args, &block) end
310
+
311
+ # colored console output support
312
+ #
313
+ This.ansi = {
314
+ :clear => "\e[0m",
315
+ :reset => "\e[0m",
316
+ :erase_line => "\e[K",
317
+ :erase_char => "\e[P",
318
+ :bold => "\e[1m",
319
+ :dark => "\e[2m",
320
+ :underline => "\e[4m",
321
+ :underscore => "\e[4m",
322
+ :blink => "\e[5m",
323
+ :reverse => "\e[7m",
324
+ :concealed => "\e[8m",
325
+ :black => "\e[30m",
326
+ :red => "\e[31m",
327
+ :green => "\e[32m",
328
+ :yellow => "\e[33m",
329
+ :blue => "\e[34m",
330
+ :magenta => "\e[35m",
331
+ :cyan => "\e[36m",
332
+ :white => "\e[37m",
333
+ :on_black => "\e[40m",
334
+ :on_red => "\e[41m",
335
+ :on_green => "\e[42m",
336
+ :on_yellow => "\e[43m",
337
+ :on_blue => "\e[44m",
338
+ :on_magenta => "\e[45m",
339
+ :on_cyan => "\e[46m",
340
+ :on_white => "\e[47m"
341
+ }
342
+ def say(phrase, *args)
343
+ options = args.last.is_a?(Hash) ? args.pop : {}
344
+ options[:color] = args.shift.to_s.to_sym unless args.empty?
345
+ keys = options.keys
346
+ keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
347
+
348
+ color = options[:color]
349
+ bold = options.has_key?(:bold)
350
+
351
+ parts = [phrase]
352
+ parts.unshift(This.ansi[color]) if color
353
+ parts.unshift(This.ansi[:bold]) if bold
354
+ parts.push(This.ansi[:clear]) if parts.size > 1
355
+
356
+ method = options[:method] || :puts
357
+
358
+ Kernel.send(method, parts.join)
359
+ end
360
+
361
+ # always run out of the project dir
362
+ #
363
+ Dir.chdir(This.dir)
364
+ }
data/lib/ggeocode.rb ADDED
@@ -0,0 +1,166 @@
1
+ module GGeocode
2
+
3
+ GGeocode::Version = '0.0.1'
4
+
5
+ def GGeocode.version
6
+ GGeocode::Version
7
+ end
8
+
9
+ require 'net/http'
10
+ require 'uri'
11
+ require 'cgi'
12
+
13
+ begin
14
+ require 'rubygems'
15
+ gem 'yajl-ruby'
16
+ gem 'map'
17
+ rescue LoadError
18
+ nil
19
+ end
20
+
21
+ require 'yajl/json_gem'
22
+ require 'map'
23
+
24
+
25
+ def geocode(string)
26
+ response = get(url_for(:address => string))
27
+ result_for(response)
28
+ end
29
+
30
+ def reverse_geocode(string)
31
+ response = get(url_for(:latlng => string))
32
+ result_for(response)
33
+ end
34
+ alias_method('rgeocode', 'reverse_geocode')
35
+
36
+ module Response
37
+ attr_accessor :response
38
+
39
+ def body
40
+ response.body
41
+ end
42
+ end
43
+
44
+ def result_for(response)
45
+ return nil unless response
46
+ hash = JSON.parse(response.body)
47
+ return nil unless hash['status']=='OK'
48
+ map = Map.new
49
+ map.extend(Response)
50
+ map.response = response
51
+ map['status'] = hash['status']
52
+ map['results'] = hash['results']
53
+ map
54
+ end
55
+
56
+ Url = URI.parse("http://maps.google.com/maps/api/geocode/json?")
57
+
58
+ def url_for(options = {})
59
+ options[:sensor] = false unless options.has_key?(:sensor)
60
+ url = Url.dup
61
+ url.query = query_for(options)
62
+ url
63
+ end
64
+
65
+ def query_for(options = {})
66
+ pairs = []
67
+ options.each do |key, values|
68
+ key = key.to_s
69
+ values = [values].flatten
70
+ values.each do |value|
71
+ value = value.to_s
72
+ if value.empty?
73
+ pairs << [ CGI.escape(key) ]
74
+ else
75
+ pairs << [ CGI.escape(key), CGI.escape(value) ].join('=')
76
+ end
77
+ end
78
+ end
79
+ pairs.replace pairs.sort_by{|pair| pair.size}
80
+ pairs.join('&')
81
+ end
82
+
83
+ def get(url)
84
+ url = URI.parse(url.to_s) unless url.is_a?(URI)
85
+ begin
86
+ Net::HTTP.get_response(url)
87
+ rescue SocketError, TimeoutError
88
+ return nil
89
+ end
90
+ end
91
+
92
+ extend(GGeocode)
93
+ end
94
+
95
+ Ggeocode = GGeocode
96
+
97
+
98
+ if $0 == __FILE__
99
+ require 'pp'
100
+
101
+ pp(GGeocode.geocode('boulder, co'))
102
+ pp(GGeocode.rgeocode('40.0149856,-105.2705456'))
103
+ end
104
+
105
+
106
+
107
+
108
+
109
+ __END__
110
+
111
+ {
112
+ "status": "OK",
113
+
114
+ "results": [ {
115
+ "types": [ "locality", "political" ],
116
+
117
+ "formatted_address": "Boulder, CO, USA",
118
+
119
+ "address_components": [ {
120
+ "long_name": "Boulder",
121
+ "short_name": "Boulder",
122
+ "types": [ "locality", "political" ]
123
+ }, {
124
+ "long_name": "Boulder",
125
+ "short_name": "Boulder",
126
+ "types": [ "administrative_area_level_2", "political" ]
127
+ }, {
128
+ "long_name": "Colorado",
129
+ "short_name": "CO",
130
+ "types": [ "administrative_area_level_1", "political" ]
131
+ }, {
132
+ "long_name": "United States",
133
+ "short_name": "US",
134
+ "types": [ "country", "political" ]
135
+ } ],
136
+
137
+ "geometry": {
138
+ "location": {
139
+ "lat": 40.0149856,
140
+ "lng": -105.2705456
141
+ },
142
+ "location_type": "APPROXIMATE",
143
+ "viewport": {
144
+ "southwest": {
145
+ "lat": 39.9465862,
146
+ "lng": -105.3986050
147
+ },
148
+ "northeast": {
149
+ "lat": 40.0833165,
150
+ "lng": -105.1424862
151
+ }
152
+ },
153
+ "bounds": {
154
+ "southwest": {
155
+ "lat": 39.9640689,
156
+ "lng": -105.3017580
157
+ },
158
+ "northeast": {
159
+ "lat": 40.0945509,
160
+ "lng": -105.1781970
161
+ }
162
+ }
163
+ }
164
+ } ]
165
+ }
166
+
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ggeocode
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ara T. Howard
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-02 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: "description: ggeocode kicks the ass"
23
+ email: ara.t.howard@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/ggeocode.rb
32
+ - Rakefile
33
+ - README
34
+ has_rdoc: true
35
+ homepage: http://github.com/ahoward/ggeocode
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ hash: 3
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project: codeforpeople
64
+ rubygems_version: 1.4.2
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: ggeocode
68
+ test_files: []
69
+