google_geocoding 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ doc
23
+ .yardoc
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rodrigo Kochenburger
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.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ = GoogleGeocoding
2
+
3
+ GoogleGeocoding is a small library for performing geocoding using the Google's HTTP geocoding API.
4
+
5
+ == Usage Example
6
+
7
+ geo = GoogleGeocoding::Geocoder.new(:app_key => YOUR_API_KEY, :user_agent => YOUR_USER_AGENT)
8
+ res = geo.query("Union Square, San Francisco, CA")
9
+ res.placemarks # => [#<GoogleGeocoding::Placemark:0x100629598 @country_code="US", @country_name=["USA", "US"], @city="San Francisco", @accurracy=4, @coordinates=[-122.4074374, 37.7879938], @region="CA">]
10
+
11
+ == Copyright
12
+
13
+ Copyright (c) 2010 Rodrigo Kochenburger. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "google_geocoding"
8
+ gem.summary = %Q{Google's geocoding library}
9
+ gem.description = %Q{GoogleGeocoding is a small library for performing geocoding using the Google's HTTP geocoding API}
10
+ gem.email = "divoxx@gmail.com"
11
+ gem.homepage = "http://github.com/divoxx/google_geocoding"
12
+ gem.authors = ["Rodrigo Kochenburger"]
13
+ gem.add_dependency "json", ">= 1.2.0"
14
+ gem.add_dependency "patron", ">= 0.4.5"
15
+ gem.add_development_dependency "rspec", ">= 1.2.9"
16
+ gem.add_development_dependency "yard", ">= 0.5.3"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ begin
41
+ require 'yard'
42
+ YARD::Rake::YardocTask.new
43
+ rescue LoadError
44
+ task :yardoc do
45
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
46
+ end
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,68 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{google_geocoding}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rodrigo Kochenburger"]
12
+ s.date = %q{2010-02-24}
13
+ s.description = %q{GoogleGeocoding is a small library for performing geocoding using the Google's HTTP geocoding API}
14
+ s.email = %q{divoxx@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "google_geocoding.gemspec",
27
+ "lib/google_geocoding.rb",
28
+ "lib/google_geocoding/errors.rb",
29
+ "lib/google_geocoding/geocoder.rb",
30
+ "lib/google_geocoding/placemark.rb",
31
+ "lib/google_geocoding/response.rb",
32
+ "spec/google_geocoding_spec.rb",
33
+ "spec/spec.opts",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/divoxx/google_geocoding}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.5}
40
+ s.summary = %q{Google's geocoding library}
41
+ s.test_files = [
42
+ "spec/google_geocoding_spec.rb",
43
+ "spec/spec_helper.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<json>, [">= 1.2.0"])
52
+ s.add_runtime_dependency(%q<patron>, [">= 0.4.5"])
53
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
54
+ s.add_development_dependency(%q<yard>, [">= 0.5.3"])
55
+ else
56
+ s.add_dependency(%q<json>, [">= 1.2.0"])
57
+ s.add_dependency(%q<patron>, [">= 0.4.5"])
58
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
59
+ s.add_dependency(%q<yard>, [">= 0.5.3"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<json>, [">= 1.2.0"])
63
+ s.add_dependency(%q<patron>, [">= 0.4.5"])
64
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
65
+ s.add_dependency(%q<yard>, [">= 0.5.3"])
66
+ end
67
+ end
68
+
@@ -0,0 +1,76 @@
1
+ module GoogleGeocoding
2
+ module Errors
3
+ # Base error for the geocoding service, all error should inherit from this one.
4
+ class BaseError < StandardError; end
5
+
6
+ # Http error, will be raised when the server returns with a status code outside the 200...300 range.
7
+ class HttpError < BaseError
8
+ def initialize(address, response)
9
+ @address = address
10
+ @response = response
11
+ super "Could not geocode '#{@address}'. Server responded with #{@response.status}"
12
+ end
13
+ end
14
+
15
+ # Services error means the service was reached but returned a unsuccessful response.
16
+ class ServiceError < BaseError; end
17
+
18
+ # 500 G_GEO_SERVER_ERROR
19
+ class ServerError < ServiceError
20
+ def initialize
21
+ super("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is unknown.")
22
+ end
23
+ end
24
+
25
+ # 601 G_GEO_MISSING_QUERY
26
+ class MissingQueryError < ServiceError
27
+ def initialize
28
+ super("An empty address was specified")
29
+ end
30
+ end
31
+
32
+ # 602 G_GEO_UNKNOWN_ADDRESS
33
+ class UnknownAddressError < ServiceError
34
+ def initialize
35
+ super("No corresponding geographic location could be found for the specified address, possibly because the address is relatively new, or because it may be incorrect.")
36
+ end
37
+ end
38
+
39
+ # 603 G_GEO_UNAVAILABLE_ADDRESS
40
+ class UnavailableAddressError < ServiceError
41
+ def initialize
42
+ super("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.")
43
+ end
44
+ end
45
+
46
+ # 610 G_GEO_BAD_KEY
47
+ class BadKeyError < ServiceError
48
+ def initialize
49
+ super("The given key is either invalid or does not match the domain for which it was given.")
50
+ end
51
+ end
52
+
53
+ # 620 G_GEO_TOO_MANY_QUERIES
54
+ class TooManyQueriesError < ServiceError
55
+ def initialize
56
+ super("The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly.")
57
+ end
58
+ end
59
+
60
+ # Extend ServiceError to include factory method based on status codes.
61
+ class ServiceError
62
+ ERRORS_MAPPING = {
63
+ 500 => ServerError,
64
+ 601 => MissingQueryError,
65
+ 602 => UnknownAddressError,
66
+ 603 => UnknownAddressError,
67
+ 610 => BadKeyError,
68
+ 620 => TooManyQueriesError
69
+ }
70
+
71
+ def self.build(status)
72
+ ERRORS_MAPPING[status].new
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,29 @@
1
+ module GoogleGeocoding
2
+ class Geocoder
3
+ # Creates a new geocoder instance.
4
+ # @see Geocoder#geocode
5
+ def initialize(options = {})
6
+ @options = options
7
+ @sess = Patron::Session.new
8
+ @sess.timeout = 5
9
+ @sess.base_url = "http://maps.google.com/maps/geo"
10
+ @sess.headers['User-Agent'] = options[:user_agent]
11
+ end
12
+
13
+ # Performs a geocoding request against google for the given address.
14
+ #
15
+ # @param [String, #to_s]
16
+ # @return [Response]
17
+ def query(address)
18
+ params = "?q=#{URI.encode(address.to_s)}"
19
+ params << "&key=#{@options[:api_key]}" if @options[:api_key]
20
+ resp = @sess.get(params)
21
+
22
+ if (200...300).include?(resp.status)
23
+ Response.new(resp.body)
24
+ else
25
+ raise GeocodeError.new(address, resp)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module GoogleGeocoding
2
+ # Model that represents a placemark returned by the geocoding service.
3
+ class Placemark
4
+ # The level of accurracy for the placemark
5
+ # @see http://code.google.com/apis/maps/documentation/geocoding/index.html#GeocodingAccuracy
6
+ attr_accessor :accurracy
7
+
8
+ # The country name
9
+ attr_accessor :country_name
10
+
11
+ # The country ISO code
12
+ # @see http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm
13
+ attr_accessor :country_code
14
+
15
+ # The region/province/state
16
+ attr_accessor :region
17
+
18
+ # The city name
19
+ attr_accessor :city
20
+
21
+ # The postal/zip code
22
+ attr_accessor :postal_code
23
+
24
+ # The street address, including the number
25
+ attr_accessor :street
26
+
27
+ # An array with two positions: latitude and longitude
28
+ attr_accessor :coordinates
29
+ end
30
+ end
@@ -0,0 +1,76 @@
1
+ module GoogleGeocoding
2
+ class Response
3
+ # Creates a new response object from the given response body, expects to be a JSON string.
4
+ #
5
+ # @param [String]
6
+ def initialize(resp_body)
7
+ @data = JSON.parse(resp_body)
8
+ end
9
+
10
+ # Return the status code included in the server response.
11
+ #
12
+ # @return [Integer]
13
+ # @see http://code.google.com/apis/maps/documentation/geocoding/index.html#StatusCodes
14
+ def status_code
15
+ Integer(@data["Status"]["code"])
16
+ end
17
+
18
+ # Return whether response successfully resolved the geolocation
19
+ def success?
20
+ status_code == 200
21
+ end
22
+
23
+ # Return whether response failed to resolved the geolocation
24
+ def failure?
25
+ !success?
26
+ end
27
+
28
+ # Return the placemarks included in the response.
29
+ #
30
+ # @return [Array<Placemark>]
31
+ def placemarks
32
+ if failure?
33
+ raise Errors::ServiceError.build(status_code)
34
+ else
35
+ @data["Placemark"].map do |placemark_data|
36
+ details = placemark_data["AddressDetails"]
37
+ coordinates = placemark_data["Point"]["coordinates"][0,2]
38
+ accurracy = Integer(details["Accuracy"])
39
+ placemark = Placemark.new
40
+ placemark.accurracy = accurracy
41
+ placemark.coordinates = coordinates
42
+
43
+ if accurracy >= 1
44
+ country = details["Country"]
45
+ placemark.country_name = country["CountryName"],
46
+ placemark.country_code = country["CountryNameCode"]
47
+
48
+ if accurracy >= 2
49
+ admarea = country["AdministrativeArea"]
50
+ placemark.region = admarea["AdministrativeAreaName"]
51
+
52
+ if accurracy >= 3
53
+ subadmarea = admarea["SubAdministrativeArea"]
54
+
55
+ if accurracy >= 4
56
+ locality = subadmarea ? subadmarea["Locality"] : admarea["Locality"]
57
+ placemark.city = locality["LocalityName"]
58
+
59
+ if accurracy >= 5
60
+ placemark.postal_code = locality["PostalCode"]["PostalCodeNumber"]
61
+ end
62
+
63
+ if accurracy >= 6
64
+ placemark.street = locality["Thoroughfare"]["ThoroughfareName"]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ placemark
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,6 @@
1
+ require 'json'
2
+ require 'patron'
3
+ require 'google_geocoding/errors'
4
+ require 'google_geocoding/placemark'
5
+ require 'google_geocoding/response'
6
+ require 'google_geocoding/geocoder'
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "GoogleGeocoding" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'google_geocoding'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google_geocoding
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rodrigo Kochenburger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-24 00:00:00 -08: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.2.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: patron
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.5
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.9
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: yard
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.3
54
+ version:
55
+ description: GoogleGeocoding is a small library for performing geocoding using the Google's HTTP geocoding API
56
+ email: divoxx@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - LICENSE
63
+ - README.rdoc
64
+ files:
65
+ - .document
66
+ - .gitignore
67
+ - LICENSE
68
+ - README.rdoc
69
+ - Rakefile
70
+ - VERSION
71
+ - google_geocoding.gemspec
72
+ - lib/google_geocoding.rb
73
+ - lib/google_geocoding/errors.rb
74
+ - lib/google_geocoding/geocoder.rb
75
+ - lib/google_geocoding/placemark.rb
76
+ - lib/google_geocoding/response.rb
77
+ - spec/google_geocoding_spec.rb
78
+ - spec/spec.opts
79
+ - spec/spec_helper.rb
80
+ has_rdoc: true
81
+ homepage: http://github.com/divoxx/google_geocoding
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options:
86
+ - --charset=UTF-8
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.5
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Google's geocoding library
108
+ test_files:
109
+ - spec/google_geocoding_spec.rb
110
+ - spec/spec_helper.rb