How To Map Cities With Vue, GeoJSON, And Google: Part 2
Location, Location, Location
We have begun to write a Vue.js app that will use a few Google Maps APIs. In this part, we’re going to start searching for locations via an autocomplete input field, and… we’re going to be able to update that field with locations that are clicked on. In other words, this will illustrate how to keep things in sync.
The repository for this project is at https://github.com/DanielSmith/citymap
This is part 2 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
Update address via Location Search or Map click
In this section:
- explain the use of Vue.js Eventbus
- use Google Maps API geocoder to get address from a click (reverse geocoding)
- use Google Maps API geocoder to get lat, lng coordinates from an address
- use location search with autocomplete to get address
- update marker and map position for most recent address
The Vue.js Eventbus
Before I get into what happens in specific sections of code, I want to take a step back, and explain a method of communicating between Vue.js components. I like using the Eventbus. For a detailed look at it, check out: A simple EventBus to communicate between Vue.js components
I use the Eventbus to send data between components. I set a separate file, and import it wherever I need it. The eventbus.js file:
As you can see, there is not much to it. I show the methods property as a placeholder. I may use it later.
Sending and Receiving over the Eventbus
Before using the Eventbus in any component, you must first import it:
import { eventBus } from '@/event-bus.js';
In Map.vue, we load in the Google Maps API javascript library. Once that is done, we can pass a message to the rest of the app, so that it can initialize anything that depends on the lib:
// In Map.vue:
// now we can init other things that depend on Google being loaded
// tell the event bus
eventBus.$emit('googleInit', {});
Over in App.vue, we use the Vue.js mounted() lifecycle method as a spot to set up Eventbus listeners:
- when the
googleInit
message is sent from Map.vue, the listener is invoked over in App.vue, and we run some code to intialize our location search (so that it can autocomplete addresses — we will cover this later in this part of our series) - when the
mapAddress
message is sent from Map.vue (from a click on the map), the listener is invoked, and we run code to update the address in the location search - to be clear, one could send messages within the same file
- $emit to send, $on to receive
Geocoding
(documentation on Geocoder: https://developers.google.com/maps/documentation/geocoding/intro)
Make sure the Geocoding API is enabled
Before getting into using the geocoder, we need to enable it over on the Google Cloud Console. Go to https://console.cloud.google.com/
Pick your project from the top menu:
Go to the Google Maps > APIs submenu:
Search for “geocode”:
Click on “Enable”. Once you step back to see all of your enabled APIs, it should look like:
Geocoder: Map to Address
Over in Map.vue, we use geocoder within the click handler for the map. An important note is that we use the eventbus to broadcast the payload (results), so that the location search field can be updated:
Geocoder: Address to Map
Over in App.vue, we have a location search that autocompletes to an address. Whenever a place changes, we use the eventbus to broadcast:
In our map, we receive the eventbus payload, recenter the map with the new location, and update the marker:
Note:updateFromTextAddress()
is called from the eventbus $on
handler.
At this point, we are able to click on the map, and have it update the Marker and update the location search. We are also able to do a location search and have that update the Map.
Initial state:
And we can go the other way, by clicking in the Map:
We’re just scratching the surface here. We’ll bring GeoJSON city boundaries in Part 3, search for places in Part 4, and, in Part 5, we will show how to filter results to be within boundaries.