Saturday, April 11, 2009

red_eye


I was going to write about OAuth for this entry, but turns out... it's broken.
So, next best thing. I stumbled across the Google Maps Geocoding API a few weeks ago. This is a REST service that is responsible for taking the text you type in the Google Maps search field and making sense of it. Google makes it clear that this service is to be used in conjunction with Google Maps:

Note: the geocoding service may only be used in conjunction with displaying results on a Google map; geocoding results without displaying them on a map is prohibited. For complete details on allowed usage, consult the Maps API Terms of Service License Restrictions.

Before the actual API is detailed, there are some terms that should be known:

Geocoding

The process of taking a human readable address and transforming it into one or more latitude, longitude coordinates.

Reverse Geocoding

The process of taking a latitude, longitude coordinate and transforming it into one or more human readable addresses.

Viewport Biasing

Instructs the geocoder to place a bias on addresses within a provided bounding box. This can help sort out ambiguous addresses like Winnetka (Chicago, IL or Los Angeles, CA?).

Country Code Biasing

Instructs the geocoder to place a bias on addresses within a country. This can help sort out addresses like Toledo (Ohio or Spain?).


The REST interface is easy to understand. The base address is:
http://maps.google.com/maps/geo?

It supports the following query parameters (bold parameters are required):

q

The address or latitude that you want to geocode. "1600 Amphitheatre Parkway, Mountain View, CA" and "40.7142298,-73.9614669" are both valid.

key

Your Google Maps API key. You can get one for free here.

sensor

Does this request come from a device with a location sensor? Unless you are using a mobile device, this is probably false.

output

The format that your client wishes the response to be in. Valid values are: xml, kml, csv and json (default).

oe

The encoding format for the response. In general, this should be 'utf8'.

ll

Used for viewport biasing. This is the center (latitude, longitude) of the bounding box the geocoder is to give preference to. e.g. ll=34.197605,-118.546944

span

Another comma separated list that specifies the length of the sides of the bounding box used for viewport biasing. This only has meaning if the ll parameter is used. I'm not 100% sure what the units are but the example I have is span=0.247048,0.294914

gl

The ccTLD country code to use for country code biasing. See this article for legal values.


I wrote a ruby wrapper around this called red_eye that can be found at github.
Nothing super fancy. Just parses the JSON response and returns ruby structs for results. It also provides some smarts around the parameter handling as well as making them more human readable (e.g. :country vs. :gl). Here is an example of how to use it: (Note: This article assumes that you have red_eye installed to an accessible place, I've never tried to install this as a gem. I usually just fire up irb with a -I./lib from the red_eye root directory.)

require 'red_eye'

#Some useful methods for printing out results
def print_placemark placemark, header = "=========="

puts header
puts "#{placemark.address}"
puts "#{placemark.point.lat},#{placemark.point.lng}"
puts "Accuracy: #{placemark.accuracy}"
end

def print_result result

puts "Success: #{result.success?}"
result.placemarks.each_with_index do |placemark, idx|
print_placemark placemark, "=========#{idx}========="
end
end

def perform_query geocoder, query, options = {}

puts "Query URL:\n#{geocoder.to_url(query, options)}"
print_result geocoder.geocode(query, options)
end

#create the work horse.
geocoder = RedEye::GeoCoder.new

#let's find google HQ
perform_query geocoder, "1600 Amphitheatre Parkway, Mountain View, CA"
#reverse geocode
perform_query geocoder, RedEye::LatLng.new(:lat => 40.714224, :lng => -73.961452)

#setup a bias for viewport bias
center = RedEye::LatLng.new :lat => 34.197605, :lng => -118.546944
bias = RedEye::Bias.new :center => center, :span => [0.247048, 0.294914]

#viewport bias geocoding
perform_query geocoder, "Winnetka", :bias => bias
#country bias geocoding
perform_query geocoder, "Toledo", :country => 'es'

No comments: