Skip to content

Commit

Permalink
Google Places Search Lookup (alexreisner#1143)
Browse files Browse the repository at this point in the history
  • Loading branch information
waruboy authored and alexreisner committed Jan 31, 2017
1 parent fb1ae03 commit 3ec4111
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 5 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ Similar to `:google`, with the following differences:

#### Google Places Details (`:google_places_details`)

The [Google Places Details API](https://developers.google.com/places/documentation/details) is not, strictly speaking, a geocoding service. It accepts a Google `place_id` and returns address information, ratings and reviews. A `place_id` can be obtained from the Google Places Autocomplete API and should be passed to Geocoder as the first search argument: `Geocoder.search("ChIJhRwB-yFawokR5Phil-QQ3zM", :lookup => :google_places_details)`.
The [Google Places Details API](https://developers.google.com/places/documentation/details) is not, strictly speaking, a geocoding service. It accepts a Google `place_id` and returns address information, ratings and reviews. A `place_id` can be obtained from the Google Places Search lookup or Google Places Autocomplete API and should be passed to Geocoder as the first search argument: `Geocoder.search("ChIJhRwB-yFawokR5Phil-QQ3zM", :lookup => :google_places_details)`.

* **API key**: required
* **Key signup**: https://code.google.com/apis/console/
Expand All @@ -434,6 +434,11 @@ The [Google Places Details API](https://developers.google.com/places/documentati
* **Terms of Service**: https://developers.google.com/places/policies
* **Limitations**: "If your application displays Places API data on a page or view that does not also display a Google Map, you must show a "Powered by Google" logo with that data."

#### Google Places Search (`:google_places_search`)
The [Google Places Search API](https://developers.google.com/places/web-service/search) is the geocoding service of Google Places API.
It only returns limited location data, however it also returns corresponding `place_id` for a given location. You can use Google Place Details if you need more detailed information using obtained `place_id`. You should use this service instead of regular Google Geocoding API if your queries are ambiguos or incomplete addresses. For more comparison between this and regular Google Geocoding API, see https://maps-apis.googleblog.com/2016/11/address-geocoding-in-google-maps-apis.html
* See points in the previous Google Places Details section.

#### Bing (`:bing`)

* **API key**: required (set `Geocoder.configure(:lookup => :bing, :api_key => key)`)
Expand Down
1 change: 1 addition & 0 deletions lib/geocoder/lookup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def street_services
:google,
:google_premier,
:google_places_details,
:google_places_search,
:bing,
:geocoder_ca,
:geocoder_us,
Expand Down
6 changes: 3 additions & 3 deletions lib/geocoder/lookups/google.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ def results(query)
return doc['results']
when "OVER_QUERY_LIMIT"
raise_error(Geocoder::OverQueryLimitError) ||
Geocoder.log(:warn, "Google Geocoding API error: over query limit.")
Geocoder.log(:warn, "#{name} API error: over query limit.")
when "REQUEST_DENIED"
raise_error(Geocoder::RequestDenied) ||
Geocoder.log(:warn, "Google Geocoding API error: request denied.")
Geocoder.log(:warn, "#{name} API error: request denied.")
when "INVALID_REQUEST"
raise_error(Geocoder::InvalidRequest) ||
Geocoder.log(:warn, "Google Geocoding API error: invalid request.")
Geocoder.log(:warn, "#{name} API error: invalid request.")
end
return []
end
Expand Down
33 changes: 33 additions & 0 deletions lib/geocoder/lookups/google_places_search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require "geocoder/lookups/google"
require "geocoder/results/google_places_search"

module Geocoder
module Lookup
class GooglePlacesSearch < Google
def name
"Google Places Search"
end

def required_api_key_parts
["key"]
end

def supported_protocols
[:https]
end

def query_url(query)
"#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?#{url_query_string(query)}"
end

private

def query_url_google_params(query)
{
query: query.text,
language: query.language || configuration.language
}
end
end
end
end
52 changes: 52 additions & 0 deletions lib/geocoder/results/google_places_search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "geocoder/results/google"

module Geocoder
module Result
class GooglePlacesSearch < Google

def types
@data["types"] || []
end

def rating
@data["rating"]
end

def photos
@data["photos"]
end

def city
""
end

def state
""
end

def state_code
""
end

def province
""
end

def province_code
""
end

def postal_code
""
end

def country
""
end

def country_code
""
end
end
end
end
42 changes: 42 additions & 0 deletions test/fixtures/google_places_search_madison_square_garden
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"html_attributions" : [],
"results" : [
{
"formatted_address" : "4 Pennsylvania Plaza, New York, NY 10001, United States",
"geometry" : {
"location" : {
"lat" : 40.75050450000001,
"lng" : -73.9934387
},
"viewport" : {
"northeast" : {
"lat" : 40.7523981,
"lng" : -73.98975269999997
},
"southwest" : {
"lat" : 40.7485721,
"lng" : -73.9963951
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "55e3174d410b31da010030a7dfc0c9819027445a",
"name" : "Madison Square Garden",
"photos" : [
{
"height" : 3904,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/117796018192827964147/photos\"\u003eAntonio Vera\u003c/a\u003e"
],
"photo_reference" : "CoQBdwAAAJSRc-oTDFp3lkRwkyDN85h49Inw9YRC8U2sPUDeV0FSKzQNMxKfswp27o4Eh8gt1U6ZLPYES3RCP-2zJPswcVMtQOE9NxxM9Yg7SJllFYcC1GR_yjCJw6OGTP3_OCaL-gFI1_r54-04veyCc-UNtzjF836se6yQlSGd643zBy3_EhCYKtc3tY024iyO-6xPZUzzGhRcgC0A-itlFq-U2qmYbPde4gJU7Q",
"width" : 3152
}
],
"place_id" : "ChIJhRwB-yFawokR5Phil-QQ3zM",
"rating" : 4.5,
"reference" : "CmRRAAAAqb-Y-BFyZh54ipS97aLZCfQYVVI_l87_7HQxJAXMx3rI29XzscexUUiwt7kLbr4YeDaggMQ78coK-V_yGztNvhsGbq2OsrdR-BmVpecrNGbiE9fNDPsPGvdxKcB3SPbAEhDTgnyzjLY1p7IPh2M4L9KnGhS7ZZMAtvVKPnjoCnaWP9IzdzRC4w",
"types" : [ "stadium", "point_of_interest", "establishment" ]
}
],
"status" : "OK"
}
5 changes: 5 additions & 0 deletions test/fixtures/google_places_search_no_results
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"html_attributions" : [],
"results" : [],
"status" : "ZERO_RESULTS"
}
50 changes: 50 additions & 0 deletions test/unit/lookups/google_places_search_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# encoding: utf-8
require 'test_helper'

class GooglePlacesSearchTest < GeocoderTestCase

def setup
Geocoder.configure(lookup: :google_places_search)
set_api_key!(:google_places_search)
end

def test_google_places_search_result_contains_place_id
assert_equal "ChIJhRwB-yFawokR5Phil-QQ3zM", madison_square_garden.place_id
end

def test_google_places_search_result_contains_latitude
assert_equal madison_square_garden.latitude, 40.75050450000001
end

def test_google_places_search_result_contains_longitude
assert_equal madison_square_garden.longitude, -73.9934387
end

def test_google_places_search_result_contains_rating
assert_equal 4.5, madison_square_garden.rating
end

def test_google_places_search_result_contains_types
assert_equal madison_square_garden.types, %w(stadium point_of_interest establishment)
end

def test_google_places_search_query_url_contains_language
url = lookup.query_url(Geocoder::Query.new("some-address", language: "de"))
assert_match(/language=de/, url)
end

def test_google_places_search_query_url_always_uses_https
url = lookup.query_url(Geocoder::Query.new("some-address"))
assert_match(%r(^https://), url)
end

private

def lookup
Geocoder::Lookup::GooglePlacesSearch.new
end

def madison_square_garden
Geocoder.search("Madison Square Garden").first
end
end
2 changes: 1 addition & 1 deletion test/unit/result_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_result_has_coords_in_reasonable_range_for_madison_square_garden
def test_result_accepts_reverse_coords_in_reasonable_range_for_madison_square_garden
Geocoder::Lookup.street_services.each do |l|
next unless File.exist?(File.join("test", "fixtures", "#{l.to_s}_madison_square_garden"))
next if [:bing, :esri, :geocoder_ca, :geocoder_us, :geoportail_lu].include? l # Reverse fixture does not match forward
next if [:bing, :esri, :geocoder_ca, :google_places_search, :geocoder_us, :geoportail_lu].include? l # Reverse fixture does not match forward
Geocoder.configure(:lookup => l)
set_api_key!(l)
result = Geocoder.search([40.750354, -73.993371]).first
Expand Down

0 comments on commit 3ec4111

Please sign in to comment.