hacked0ff-reverse_geocode 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 YOUR NAME
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,3 @@
1
+ ReverseGeocode
2
+
3
+ A small wrapper gem for Reverse Geocoding coordinated using the Google Maps API
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'date'
5
+ require 'spec/rake/spectask'
6
+
7
+ GEM = "reverse_geocode"
8
+ GEM_VERSION = "0.0.1"
9
+ AUTHOR = "Your Name"
10
+ EMAIL = "Your Email"
11
+ HOMEPAGE = "http://example.com"
12
+ SUMMARY = "A gem that provides..."
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = GEM
16
+ s.version = GEM_VERSION
17
+ s.platform = Gem::Platform::RUBY
18
+ s.has_rdoc = true
19
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
20
+ s.summary = SUMMARY
21
+ s.description = s.summary
22
+ s.author = AUTHOR
23
+ s.email = EMAIL
24
+ s.homepage = HOMEPAGE
25
+
26
+ # Uncomment this to add a dependency
27
+ # s.add_dependency "foo"
28
+
29
+ s.require_path = 'lib'
30
+ s.autorequire = GEM
31
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
32
+ end
33
+
34
+ task :default => :spec
35
+
36
+ desc "Run specs"
37
+ Spec::Rake::SpecTask.new do |t|
38
+ t.spec_files = FileList['spec/**/*_spec.rb']
39
+ t.spec_opts = %w(-fs --color)
40
+ end
41
+
42
+
43
+ Rake::GemPackageTask.new(spec) do |pkg|
44
+ pkg.gem_spec = spec
45
+ end
46
+
47
+ desc "install the gem locally"
48
+ task :install => [:package] do
49
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
50
+ end
51
+
52
+ desc "create a gemspec file"
53
+ task :make_spec do
54
+ File.open("#{GEM}.gemspec", "w") do |file|
55
+ file.puts spec.to_ruby
56
+ end
57
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/<%= name %>.rb
@@ -0,0 +1,92 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ class ReverseGeocode
6
+ class GeocodeError < StandardError
7
+ ERRORS = {
8
+ 400 => "Bad Request",
9
+ 500 => "Server Error",
10
+ 601 => "Missing Query or Address",
11
+ 602 => "Unknown Address",
12
+ 603 => "Unavailable Address",
13
+ 604 => "Unknown Directions",
14
+ 610 => "Bad Key",
15
+ 620 => "Too Many Queries"
16
+ }
17
+
18
+ def initialize(error_code)
19
+ super("#{error_code}: #{ERRORS[error_code]}")
20
+ end
21
+ end
22
+
23
+ class << self; attr_accessor :api_key; end
24
+
25
+ attr_reader :lat, :long
26
+ def initialize(lat, long)
27
+ raise ArgumentError, "Latitude and longitude required" unless lat && long
28
+ @lat, @long = lat, long
29
+ end
30
+
31
+ def response
32
+ @response ||= handle_response
33
+ end
34
+
35
+ def address
36
+ @address ||= first_placemark/'address'
37
+ end
38
+
39
+ def street
40
+ @street ||= first_administrative_area/'Thoroughfare'/'ThoroughfareName'
41
+ end
42
+
43
+ def state
44
+ @state ||= first_administrative_area/'AdministrativeAreaName'
45
+ end
46
+
47
+ def zip
48
+ @zip ||= first_administrative_area/'PostalCode'/'PostalCodeNumber'
49
+ end
50
+
51
+ def city
52
+ @city ||= placemark[1]/'AddressDetails'/'Country'/'AdministrativeArea'/'Locality'/'LocalityName'
53
+ end
54
+
55
+ def county
56
+ @county ||= (placemark[3]/'AddressDetails'/'Country'/'AdministrativeArea'/'AddressLine').first
57
+ end
58
+
59
+ private
60
+
61
+ def first_placemark
62
+ placemark[0]
63
+ end
64
+
65
+ def first_administrative_area
66
+ first_placemark/'AddressDetails'/'Country'/'AdministrativeArea'
67
+ end
68
+
69
+ def placemark
70
+ (response/"Placemark")
71
+ end
72
+
73
+ def reverse_geocode_uri
74
+ URI.parse("http://maps.google.com/maps/geo?ll=#{URI.escape(lat.to_s)},#{URI.escape(long.to_s)}&output=json")
75
+ end
76
+
77
+ def parse_json
78
+ body = Net::HTTP.get_response(reverse_geocode_uri).body
79
+ JSON.parse(body)
80
+ end
81
+
82
+ def handle_response
83
+ hash = parse_json
84
+ status_code = (hash/'Status'/'code').to_i
85
+ raise GeocodeError, status_code if status_code >= 400
86
+ return hash
87
+ end
88
+ end
89
+
90
+ class Hash
91
+ alias_method :/, :[]
92
+ end
@@ -0,0 +1,164 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "ReverseGeocode" do
4
+ before do
5
+ @attrs = {
6
+ :lat => 30.009897,
7
+ :long => -81.387655,
8
+ :address => "439-499 La Travesia Flora, FL 32095, USA",
9
+ :street => "439-499 La Travesia Flora",
10
+ :state => "FL",
11
+ :city => "St Augustine",
12
+ :zip => "32095",
13
+ :county => "St Johns"
14
+ }
15
+
16
+ @response = {"Status"=>{"code"=>200, "request"=>"geocode"},
17
+ "name"=>"30.009897,-81.387655",
18
+ "Placemark"=>
19
+ [{"AddressDetails"=>
20
+ {"Country"=>
21
+ {"AdministrativeArea"=>
22
+ {"Thoroughfare"=>{"ThoroughfareName"=>@attrs[:street]},
23
+ "PostalCode"=>{"PostalCodeNumber"=>@attrs[:zip]},
24
+ "AdministrativeAreaName"=>@attrs[:state]},
25
+ "CountryName"=>"USA",
26
+ "CountryNameCode"=>"US"},
27
+ "Accuracy"=>8},
28
+ "id"=>"p1",
29
+ "ExtendedData"=>
30
+ {"LatLonBox"=>
31
+ {"east"=>-81.3845068,
32
+ "south"=>30.0067498,
33
+ "west"=>-81.390802,
34
+ "north"=>30.013045}},
35
+ "Point"=>{"coordinates"=>[-81.3876544, 30.0098974, 0]},
36
+ "address"=> @attrs[:address]},
37
+ {"AddressDetails"=>
38
+ {"Country"=>
39
+ {"AdministrativeArea"=>
40
+ {"Locality"=>
41
+ {"LocalityName"=>@attrs[:city],
42
+ "PostalCode"=>{"PostalCodeNumber"=>@attrs[:zip]}},
43
+ "AdministrativeAreaName"=>"FL"},
44
+ "CountryName"=>"USA",
45
+ "CountryNameCode"=>"US"},
46
+ "Accuracy"=>5},
47
+ "id"=>"p2",
48
+ "ExtendedData"=>
49
+ {"LatLonBox"=>
50
+ {"east"=>-81.313069,
51
+ "south"=>29.929597,
52
+ "west"=>-81.498143,
53
+ "north"=>30.086469}},
54
+ "Point"=>{"coordinates"=>[-81.4059186, 29.9934528, 0]},
55
+ "address"=>"St Augustine, FL 32095, USA"},
56
+ {"AddressDetails"=>
57
+ {"Country"=>
58
+ {"AdministrativeArea"=>
59
+ {"AddressLine"=>["St Augustine"], "AdministrativeAreaName"=>"FL"},
60
+ "CountryName"=>"USA",
61
+ "CountryNameCode"=>"US"},
62
+ "Accuracy"=>4},
63
+ "id"=>"p3",
64
+ "ExtendedData"=>
65
+ {"LatLonBox"=>
66
+ {"east"=>-81.194405,
67
+ "south"=>29.767845,
68
+ "west"=>-81.63343,
69
+ "north"=>30.18062}},
70
+ "Point"=>{"coordinates"=>[-81.3839326, 30.0149544, 0]},
71
+ "address"=>"St Augustine, Florida, USA"},
72
+ {"AddressDetails"=>
73
+ {"Country"=>
74
+ {"AdministrativeArea"=>
75
+ {"AddressLine"=>[@attrs[:county]], "AdministrativeAreaName"=>"FL"},
76
+ "CountryName"=>"USA",
77
+ "CountryNameCode"=>"US"},
78
+ "Accuracy"=>3},
79
+ "id"=>"p4",
80
+ "ExtendedData"=>
81
+ {"LatLonBox"=>
82
+ {"east"=>-81.150818,
83
+ "south"=>29.622428,
84
+ "west"=>-81.69039,
85
+ "north"=>30.253036}},
86
+ "Point"=>{"coordinates"=>[-81.4278984, 29.9719419, 0]},
87
+ "address"=>"St Johns, Florida, USA"},
88
+ {"AddressDetails"=>
89
+ {"Country"=>
90
+ {"AdministrativeArea"=>{"AdministrativeAreaName"=>"FL"},
91
+ "CountryName"=>"USA",
92
+ "CountryNameCode"=>"US"},
93
+ "Accuracy"=>2},
94
+ "id"=>"p5",
95
+ "ExtendedData"=>
96
+ {"LatLonBox"=>
97
+ {"east"=>-79.974307,
98
+ "south"=>24.396308,
99
+ "west"=>-87.634643,
100
+ "north"=>31.001056}},
101
+ "Point"=>{"coordinates"=>[-81.5157535, 27.6648274, 0]},
102
+ "address"=>"Florida, USA"},
103
+ {"AddressDetails"=>
104
+ {"Country"=>{"CountryName"=>"USA", "CountryNameCode"=>"US"},
105
+ "Accuracy"=>1},
106
+ "id"=>"p6",
107
+ "ExtendedData"=>
108
+ {"LatLonBox"=>
109
+ {"east"=>-65.168504,
110
+ "south"=>17.83151,
111
+ "west"=>172.347848,
112
+ "north"=>71.434357}},
113
+ "Point"=>{"coordinates"=>[-95.712891, 37.09024, 0]},
114
+ "address"=>"United States"}]}
115
+
116
+ Net::HTTP.stub!(:get_response)
117
+ @reverse_geocode = ReverseGeocode.new(@attrs[:lat], @attrs[:long])
118
+ @reverse_geocode.stub!(:parse_json).and_return(@response)
119
+ end
120
+
121
+ %w( lat long address street state city zip county ).each do |attr|
122
+ describe "##{attr}" do
123
+ it {@reverse_geocode.send(attr).should == @attrs[attr.to_sym]}
124
+ end
125
+ end
126
+
127
+ describe "without a latitude or longitude" do
128
+ it "should raise an ArgumentError" do
129
+ lambda { ReverseGeocode.new(nil, 1) }.should raise_error(ArgumentError)
130
+ lambda { ReverseGeocode.new(1, nil) }.should raise_error(ArgumentError)
131
+ end
132
+ end
133
+
134
+ describe "when the response is a" do
135
+ def error_json(code)
136
+ {"Status"=>{"code"=>code, "request"=>"geocode"}, "name"=>""}
137
+ end
138
+
139
+ errors = {
140
+ 400 => "Bad Request",
141
+ 500 => "Server Error",
142
+ 601 => "Missing Query or Address",
143
+ 602 => "Unknown Address",
144
+ 603 => "Unavailable Address",
145
+ 604 => "Unknown Directions",
146
+ 610 => "Bad Key",
147
+ 620 => "Too Many Queries"
148
+ }
149
+
150
+ errors.each do |code, message|
151
+ describe code.to_s do
152
+ before do
153
+ @reverse_geocode.stub!(:parse_json).and_return(error_json(code))
154
+ end
155
+
156
+ it "should raise a GeocodeError" do
157
+ lambda {
158
+ @reverse_geocode.send(:handle_response)
159
+ }.should raise_error(ReverseGeocode::GeocodeError, "#{code}: #{message}")
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'fake_web'
3
+
4
+ $TESTING=true
5
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
6
+ require 'reverse_geocode'
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hacked0ff-reverse_geocode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tommy Campbell & ReinH
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-20 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.1.3
24
+ version:
25
+ description: A gem that provides Reverse Geocoding using the Google Maps API
26
+ email: tommycampbell@mindspring.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ - TODO
35
+ files:
36
+ - LICENSE
37
+ - README
38
+ - Rakefile
39
+ - TODO
40
+ - lib/reverse_geocode.rb
41
+ - spec/reverse_geocode_spec.rb
42
+ - spec/spec_helper.rb
43
+ has_rdoc: true
44
+ homepage: http://example.com
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: A gem that provides Reverse Geocoding using the Google Maps API
69
+ test_files: []
70
+