âĄÂ GMapsBook.com is crafted by Jozef Sorocin (đąÂ Book a consulting hour) and powered by:
- g-Xperts (Google Cloud & Business Profile Partner)
- Spatialized.io (Elasticsearch & Google Maps consulting).
- and Garages-Near-Me.com (Effortless parking across Germany)
Â
The Geocoding APIClient-sideServer-sideThe Places APIClient-side autocomplete widgetsThe Autocomplete classThe AutocompleteService classThe PlacesService classServer-side APIsSimilarities between the Geocoding & Places APIsNuances of the Geocoding & Places APIsBest practicesGeneral tipsCost optimizationsUse Session Tokens to bundle API callsUse the âsufficientâ APIFurther reading
Â
So far weâve talked about purely visual Maps APIs â the Javascript API and the Static API.
The Google Maps Platform suite offers two more incredibly useful APIs:
- the Geocoding Service & API
- and the Places Autocomplete & API.
The scopes of these two APIs overlap heavily so in this chapter, you will learn how to distinguish between them, how to use them in conjunction, and when to deploy each independently.
Â
First off, letâs clarify some terminology.
The Geocoding API
Geocoding is the process of turning an address into coordinates (latitude & longitude.)
Generally speaking, youâd use the Geocoding API to transform:
- unambiguous postal addresses
- as well as incomplete, poorly formatted, or misspelled addresses
into full, properly formatted addresses with latitude & longitude and clearly separated address components â street name & house number, district, postal code, administrative area, country name, and the 2-letter country ISO code.
For instance, given the query Cobrugurgbastei 1
(purposefully misspelled "Coburgbastei", a street in Vienna, Austria), the Geocoding API will respond with the formatted address Coburgbastei 1, 1010 Wien, Austria
and the individual address components:
street:
Coburgbastei
house number: 1
district: Innere Stadt
postal code: 1010
administrative area: Vienna
city: Vienna
country: Austria
country ISO code: AT
Plus the coordinates:
latitude:
48.20585690
longitude: 16.3775195
Note that the available address components vary by country and region. Youâll learn how to transform Googleâs geocoding response into a structure like this later on.
Client-side
You can geocode address strings using the client-side Javascript Geocoder
module:
(async () => {
// instantiate the Geocoder class
const geocoder = new google.maps.Geocoder();
// asynchronously obtain the 'results'
const { results } = await geocoder.geocode({
address: 'Coburgbastei Wien',
});
const result = results[0];
// extract the fully matched address and the related geometry
const { formatted_address, address_components, geometry } = result;
const { location } = geometry;
console.info({ formatted_address, address_componets, location });
})();
Â
Server-side
Or, reach for the corresponding server-side Node.js @googlemaps/google-maps-services-js
module:
import { Client } from '@googlemaps/google-maps-services-js';
const geoClient = new Client();
const { data } = await geoClient.geocode({
params: {
key: 'AIza...', // use your backend key
address: 'Coburgbastei Wien',
},
});
const { results } = data;
const result = results[0];
// extract the fully matched address and the related geometry
const { formatted_address, address_components, geometry } = result;
const { location } = geometry;
console.info({ formatted_address, location });
Â
Either of these calls would print:
{
formatted_address: 'Coburgbastei, 1010 Wien, Austria',
location: { lat: 48.2055761, lng: 16.3769497 },
address_components: [{"long_name":"1","short_name":"1","types":["street_number"]},{"long_name":"Coburgbastei","short_name":"Coburgbastei","types":["route"]},{"long_name":"Innere Stadt","short_name":"Innere Stadt","types":["political","sublocality","sublocality_level_1"]},{"long_name":"Wien","short_name":"Wien","types":["locality","political"]},{"long_name":"Wien","short_name":"Wien","types":["administrative_area_level_2","political"]},{"long_name":"Wien","short_name":"Wien","types":["administrative_area_level_1","political"]},{"long_name":"Austria","short_name":"AT","types":["country","political"]},{"long_name":"1010","short_name":"1010","types":["postal_code"]}]
}
Â
Tip: import the Google Maps Platform Postman collection to quickly experiment with the available APIs:
Â
Pro tip: The Geocoding API accepts an
address
parameter as well as a latlng
.
Still, Googleâs systems are smart enough to accept lat/lng strings in the address
field as well so if your applicationâs geocoding feature needs to handle both string addresses and/or lat/lng lookups, you can pass the user queries inside the address
parameter.Â
Notice the 3rd highlighted query parameter â
place_id
. What does that have to do with geocoding?The Places API
Virtually all results returned by Googleâs geocoding service will include a
place_id
. Place IDs are available for most locations, including businesses, landmarks, parks, and intersections.
Keep in mind that it is possible for the same place or location to have multiple different place IDs and that they may change over time.
Google employs Place IDs extensively throughout Google Maps â and for a good reason. Oftentimes, multiple real-world points of interest may be located at the very same coordinates (think multi-floor office buildings housing dozens of firms) â so coordinates alone arenât enough to determine a uniqueness of a place.
Now, the vast collection of Googleâs places can searched using the dedicated Places API.
Somewhat counter-intuitively, Google assigns a
place_id
even to places without a clear business-related aspect. For instance, geocoding this random point in a forest near Vienna, Austria, returns place_id=ChIJYxYVPuKmbUcRtz8-hHCmQpA
:The details behind an arbitrary
place_id
can be retrieved:Either using the client-side Javascript PlacesService
module:
Import the
places
library first:< script async defer
src=".../maps/api/js?key=YOUR_KEY_STARTING_WITH_AIza&libraries=places&callback=initMap">
Then run
.getDetails()
:(async () => {
placesService.getDetails(
{
placeId: 'ChIJv3zAHAmobUcRyYvq5F26aU4',
fields: ['all'], // the `fields` attribute is compulsory; more on this later
},
function (results, status) {
console.info({ results, status });
}
);
})();
Or via the server-side Node.js @googlemaps/google-maps-services-js
module:
import { Client } from '@googlemaps/google-maps-services-js';
const geoClient = new Client();
const { data } = await geoClient.placeDetails({
params: {
key: 'AIza...', // use your backend key
place_id: 'ChIJYxYVPuKmbUcRtz8-hHCmQpA'
},
});
Either of these requests returns something along the lines of:
{
"address_components": [...],
"formatted_address": "Schönbrunner SchloĂstraĂe 47, 1130 Wien, Austria",
"geometry": {...},
"business_status": "OPERATIONAL",
"current_opening_hours": {...},
"formatted_phone_number": "01 81113239",
"international_phone_number": "+43 1 81113239",
"name": "Schönbrunn Palace",
"opening_hours": {...},
"photos": [],
"place_id": "ChIJv3zAHAmobUcRyYvq5F26aU4",
"rating": 4.7,
"reviews": [...],
"types": [
"tourist_attraction",
"museum",
"point_of_interest",
"establishment"
],
"user_ratings_total": 126172,
"website": "https://www.schoenbrunn.at/",
}
ChIJv3zAHAmobUcRyYvq5F26aU4
In contrast to the Geocoding response, the Place Details response is much richer.
Aside from the familiar
address_components
and geometry
attributes, there are also:- Contact Data Fields like
international_phone_number
- and Atmosphere Data Fields like
rating
,reviews
, anduser_rating_total
.
Weâll come back to these extra fields later.
Â
Generally speaking, youâd utilize the Places API to respond to user input â and do so as fast as possible:
- If youâre building a ride-hailing app, your users will likely request rides to points of interest (POIs) like bars and restaurants.
- If youâre optimizing the checkout experience for your meal delivery app, youâll want to pre-fill the address form when the buyer selects a suggestion from the autocomplete dropdown.
Â
To respond to user input, youâll need an address autocompletion widget.
Client-side autocomplete widgets
The Autocomplete
class
In contrast to the Geocoder
class, the client-side Autocomplete
class binds directly to an HTML <input>
element, reacts to keydown
events, and renders PlaceResult
suggestions out of the box:
<body>
<input id="addressAutocomplete" placeholder="Where to go?" />
<script src="https://maps.googleapis.com/maps/api/js?key=AIza...&callback=initMap&libraries=places"></script>
</body>
const initMap = () => {
// instantiate the autocomplete widge
const autocomplete = new google.maps.places.Autocomplete(
// bind it to the `input` element
document.getElementById('addressAutocomplete') as HTMLInputElement,
// restrict the returnable fields
{
fields: ['formatted_address', 'geometry', 'name', 'place_id'],
}
);
// listen to the place selection event
autocomplete.addListener('place_changed', () => {
// notice that the callback doesn't include arguments
// -> you'll need to call `.getPlace()` on the `autocomplete` instance
const selectedPlace = autocomplete.getPlace();
console.info({ selectedPlace });
});
}
declare global {
interface Window {
initMap: () => void;
}
}
window.initMap = initMap;
You can style the dropdown container and the individual place suggestions according to this guide.
Â
đ The upsides of the
Autocomplete
widget are as follows: