Class: Graticule::Geocoder::Google

Inherits:
Rest
  • Object
show all
Defined in:
lib/graticule/geocoder/google.rb

Overview

First you need a Google Maps API key. You can register for one here: www.google.com/apis/maps/signup.html

Then you create a GoogleGeocode object and start locating addresses:

require 'rubygems'
require 'graticule'

gg = Graticule.service(:google).new(:key => MAPS_API_KEY)
location = gg.locate '1600 Amphitheater Pkwy, Mountain View, CA'
p location.coordinates

Constant Summary collapse

PRECISION =
{
  0 => :unknown,      # Unknown location. (Since 2.59)
  1 => :country,      # Country level accuracy. (Since 2.59)
  2 => :state,        # Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
  3 => :state,        # Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
  4 => :city,         # Town (city, village) level accuracy. (Since 2.59)
  5 => :zip,          # Post code (zip code) level accuracy. (Since 2.59)
  6 => :street,       # Street level accuracy. (Since 2.59)
  7 => :street,       # Intersection level accuracy. (Since 2.59)
  8 => :address       # Address level accuracy. (Since 2.59)
}

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Google

Creates a new GoogleGeocode that will use Google Maps API key key. You can sign up for an API key here:

www.google.com/apis/maps/signup.html



37
38
39
40
# File 'lib/graticule/geocoder/google.rb', line 37

def initialize(key)
  @key = key
  @url = URI.parse 'http://maps.google.com/maps/geo'
end

Instance Method Details

#check_error(xml) ⇒ Object

Extracts and raises an error from xml, if any.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/graticule/geocoder/google.rb', line 65

def check_error(xml) #:nodoc:
  status = xml.elements['/kml/Response/Status/code'].text.to_i
  case status
  when 200 then # ignore, ok
  when 500 then
    raise Error, 'server error'
  when 601 then
    raise AddressError, 'missing address'
  when 602 then
    raise AddressError, 'unknown address'
  when 603 then
    raise AddressError, 'unavailable address'
  when 610 then
    raise CredentialsError, 'invalid key'
  when 620 then
    raise CredentialsError, 'too many queries'
  else
    raise Error, "unknown error #{status}"
  end
end

#locate(address) ⇒ Object

Locates address returning a Location



43
44
45
# File 'lib/graticule/geocoder/google.rb', line 43

def locate(address)
  get :q => address.is_a?(String) ? address : location_from_params(address).to_s
end

#make_url(params) ⇒ Object

Creates a URL from the Hash params. Automatically adds the key and sets the output type to ‘xml’.



88
89
90
91
92
93
# File 'lib/graticule/geocoder/google.rb', line 88

def make_url(params) #:nodoc:
  params[:key] = @key
  params[:output] = 'xml'

  super params
end

#parse_response(xml) ⇒ Object

Extracts a Location from xml.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/graticule/geocoder/google.rb', line 48

def parse_response(xml) #:nodoc:
  address = REXML::XPath.first(xml, '//xal:AddressDetails', 'xal' => "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")

  longitude, latitude, = xml.elements['/kml/Response/Placemark/Point/coordinates'].text.split(',').map { |v| v.to_f }

  Location.new \
    :street => value(address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/Thoroughfare/ThoroughfareName/text()']),
    :locality => value(address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/LocalityName/text()']),
    :region => value(address.elements['Country/AdministrativeArea/AdministrativeAreaName/text()']),
    :postal_code => value(address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/PostalCode/PostalCodeNumber/text()']),
    :country => value(address.elements['Country/CountryNameCode/text()']),
    :latitude => latitude,
    :longitude => longitude,
    :precision => PRECISION[address.attribute('Accuracy').value.to_i] || :unknown
end