Searching With Google Places
This is part 4 of 5.
- Part 1: Set up Vue.js + Google Maps (move marker when clicked)
- Part 2: Location searching with autocomplete, or update location via mouse click
- Part 3: Get GeoJSON data from nominatim, and draw city boundaries on map
- Part 4: Search via Google Places API, with a fixed radius
- Part 5: Filter search results to occur within boundaries
The repository for this project is at https://github.com/DanielSmith/citymap
In this section, we’re going to submit keyword searches to Google Places, and we will get back information about businesses and other points of interest. The Google Places API is a little tricky to work with (other APIs such as Yelp, or Foursquare, are more flexible to deal with in terms of pagination, and the number of results that can be obtained). I wrote about some Places API specifics at “Making API faces at Google Maps and Places”.
I am trying to limit the scope of how many things you would need to sign up for, in order to recreate my example. For that reason, I will stick to the Google Places Search API.
We’re going to keep it simple: keyword search with a fixed radius of 500 meters.
In this section:
- update UI
- update Eventbus in Map.vue
- call Google Places API nearbySearch()
- show markers for results
This section is a bit of a breather before Part 5, where we get into filtering results against polygons… As always, please refer to the repo at https://github.com/DanielSmith/citymap — I do not refer to every new line of code here in the article.
Updating the UI
We add a text field and button for submitting a keyword search:
Note: Google Places allows AND and OR searches. Not only can you search on “coffee”, but you could try “coffee AND yoga”, or “coffee OR yoga”. Try it and see how it affects your results.
We pick up a new model here:
theKeyword. We also use Eventbus to communicate the keyword string over to our Map component:
Update Eventbus in Map.vue
The flow of communicating keywords to search in the Map component looks like this:
Note that I deliberately have a method called
doKeywordSearch(), so that there is a convenient spot to launch searches for other APIs.
I note that
doSearch() could be named to be more specific to Google. I would change the name if I were using multiple APIs.
Call Google Places API nearbySearch()
I really prefer how other APIs (such as Yelp) handle pagination. They provide a total of how many results are available, and then you grab chunks of data with successive calls (using offsets), until you have retrieved everything. Google is a bit different, in that you look for a parameter in your results to see if you need to call again.
There are many approaches to this. I opted to reference my outer scope, and check to see if there is a
I should rewrite this in more of an ES6 style.
I use a simple sleep to put a little pause between API calls (use await when calling this):
Show markers for results
As we get our results, we show Markers on the map. You can see the names of places when you hover over a Marker. It is easy to attach an info window to a Marker, in order to show photos and other data. That’s beyond the scope of this article though (I’m focused on setting the stage for filtering against GeoJSON-provided City Boundaries)
We map through our results, creating Markers, placing each one on the map:
This is separate from the Marker we move around when we click on the Map, or do an address search.