diff --git a/README.rdoc b/README.rdoc index 426dc40769a883ec1c1ec0a4665ad924a7ba7fa3..9e6e0d6993eb68ee9dcffbec865c1eb8265903ce 100644 --- a/README.rdoc +++ b/README.rdoc @@ -178,8 +178,6 @@ If anyone has a more elegant solution to this problem I am very interested in se * also need to make sure 'mysql2' is supported * make 'near' scope work with AR associations * http://stackoverflow.com/questions/3266358/geocoder-rails-plugin-near-search-problem-with-activerecord -* unobtrusively add ability to get a result with more data (Geocoder object?) - * the default usage should remain dead simple Copyright (c) 2009-11 Alex Reisner, released under the MIT license diff --git a/lib/geocoder.rb b/lib/geocoder.rb index fee7fabbd7d3b252e426620f7813c43effd47ad1..918163ccf747838b271d068288228889a07dd2da 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -1,7 +1,26 @@ require "geocoder/calculations" require "geocoder/lookup" +require "geocoder/result" require "geocoder/active_record" +module Geocoder + extend self + + ## + # Takes a search string (eg: "Mississippi Coast Coliseumf, Biloxi, MS") for + # geocoding, or coordinates (latitude, longitude) for reverse geocoding. + # Returns a Geocoder::Result object. + # + def search(*args) + if args.size == 2 + Lookup.search(args[0], args[1], true) + else + Lookup.search(args[0], false) + end + end +end + + ## # Add geocoded_by method to ActiveRecord::Base so Geocoder is accessible. # diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb index fd2ae65fcf8ac0127644e51873e863a8954c0ccb..96b8d16e5197c988965075f60c4748d70f904128 100644 --- a/lib/geocoder/lookup.rb +++ b/lib/geocoder/lookup.rb @@ -29,10 +29,14 @@ module Geocoder ## # Query Google for geographic information about the given phrase. - # Returns a Result object containing all data returned by Google. + # Returns an array of Geocoder::Result objects. # def search(query, reverse = false) - # TODO + [].tap do |results| + if doc = parsed_response(query, reverse) + doc['results'].each{ |r| results << Result.new(r) } + end + end end diff --git a/lib/geocoder/result.rb b/lib/geocoder/result.rb new file mode 100644 index 0000000000000000000000000000000000000000..e63f2263dda3a3706ad622f6926497a6744dc076 --- /dev/null +++ b/lib/geocoder/result.rb @@ -0,0 +1,42 @@ +module Geocoder + class Result + attr_accessor :data + + ## + # Takes a hash of result data from a parsed Google result document. + # + def initialize(data) + @data = data + end + + def types + @data['types'] + end + + def formatted_address + @data['formatted_address'] + end + + def address_components + @data['address_components'] + end + + ## + # Get address components of a given type. Valid types are defined in + # Google's Geocoding API documentation and include (among others): + # + # :street_number + # :locality + # :neighborhood + # :route + # :postal_code + # + def address_components_of_type(type) + address_components.select{ |c| c['types'].include?(type.to_s) } + end + + def geometry + @data['geometry'] + end + end +end diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb index 83b4c51a0c16d1e8e890af97ca5375d9de0763f1..7b8c0ff5e1c192f9e324095eecd44a45635dbabc 100644 --- a/test/geocoder_test.rb +++ b/test/geocoder_test.rb @@ -27,4 +27,10 @@ class GeocoderTest < Test::Unit::TestCase l.fetch_coordinates end end + + def test_result_address_components_of_type + results = Geocoder::Lookup.search("Madison Square Garden, New York, NY") + assert_equal "Manhattan", + results.first.address_components_of_type(:sublocality).first['long_name'] + end end