This is part three of my series on Google Maps integration. In part one I looked at the tools that Google Maps provides for free, in part two I provided an overview of the tools available through the Google Maps API and showed you how to create a Google Maps account. In this installment of the series, I’ll show you how to use the Google Maps API to get coordinates and driving directions for addresses in your FileMaker application.
Geocoding API
I’ll start with a simple API that also happens to be one of the most useful, Geocoding. The Geocoding API takes a mailing address and returns latitude and longitude or vice versa.
Having latitude and longitude for an address opens a lot of doors. Once you have these you can:
- Shorten the length of the URL you send to the Google Maps URL so you can fit in more destinations.
- Calculate the distance between two locations.
- Simplify calls to other Google Maps APIs.
In addition to the location’s latitude and longitude the Geocoding API also returns the original address broken down into separate components. This can be very useful if you’ve been given the full address and need to parse it into separate fields.
Geocoding API requests take the form:
https://maps.googleapis.com/maps/api/geocode/outputFormat?parameters
The output format can be either JSON or XML. I’ll be using JSON in all my examples.
Documentation for the Geocoding API can be found here:
https://developers.google.com/maps/documentation/geocoding
The full list of parameters that can be used in the request is listed in the documentation referenced above, but the only ones required for our purposes are Address and API key.
Address – The street address that you want to geocode, encoded as a URL. Elements such as business name, suite, or floor numbers should be avoided. Street address elements should be delimited by spaces, not commas.
API Key – The key you generated when you set up your Google Maps account.
I’ll be building on the demo file from part 1 of this series. As you may recall that database is filled with Starbucks locations whose addresses I’ll be using in my examples.
Hopefully, I remembered to remove my API Key from the demo file before posting it with this article. You will need to generate an API Key of your own and enter it into the Settings table of the demo file before you can run these scripts.
The Get Latitude and Longitude from Google
script demonstrates how to use the Geocoding API.
Here’s an example of how the request might be formatted and the result that the Geocoding API returns:
https://maps.googleapis.com/maps/api/geocode/json?address=2901%20W%20Broadway%20Suite%20117%20Columbia%20MO%2065203%20US&key=AAAAAAABBBBBBBCCCCCCCDDDDDEEEEEFFFFF
Result:
{
"results" : [
{
"address_components" : [
{
"long_name" : "117",
"short_name" : "117",
"types" : [ "subpremise" ]
},
{
"long_name" : "2901",
"short_name" : "2901",
"types" : [ "street_number" ]
},
{
"long_name" : "West Broadway",
"short_name" : "W Broadway",
"types" : [ "route" ]
},
{
"long_name" : "Columbia",
"short_name" : "Columbia",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Missouri Township",
"short_name" : "Missouri Township",
"types" : [ "administrative_area_level_3", "political" ]
},
{
"long_name" : "Boone County",
"short_name" : "Boone County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Missouri",
"short_name" : "MO",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "65203",
"short_name" : "65203",
"types" : [ "postal_code" ]
},
{
"long_name" : "0669",
"short_name" : "0669",
"types" : [ "postal_code_suffix" ]
}
],
"formatted_address" : "2901 W Broadway #117, Columbia, MO 65203, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 38.9555688,
"lng" : -92.3810774
},
"southwest" : {
"lat" : 38.9553417,
"lng" : -92.38121199999999
}
},
"location" : {
"lat" : 38.95546700000001,
"lng" : -92.38111139999999
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 38.9567492802915,
"lng" : -92.3796293697085
},
"southwest" : {
"lat" : 38.9540513197085,
"lng" : -92.3823273302915
}
}
},
"place_id" : "ChIJ3UlygQe23IcR-hBaBkLhfs8",
"types" : [ "subpremise" ]
}
],
"status" : "OK"
}
As you can see, I get much more than just the latitude and longitude. For a full breakdown of the results, consult the API documentation.
The following script steps will allow us to snag the latitude and longitude from the result and put them in the proper fields:
As I mentioned before, having the latitude and longitude for the address simplifies our other calls to Google Maps. If you remember the final example in part one of this series, I made calls to the Google Maps URL to generate driving directions using the full address of each location. Now that I have the latitude and longitude for my addresses, I can replace this request:
https://www.google.com/maps/dir/?api=1&origin=
2901+W+Broadway%2C+Columbia+MO&destination=2400+Bernadette+Dr+
Columbia+MO&travelmode=driving&waypoints=1729+W+Broadway+Columbia+MO%7C
3100+W+Broadway+Columbia+MO
with this shorter one:
https://www.google.com/maps/dir/?api=1&origin=38.9638174%2C-92.3772164&destination=38.955467%2C-92.3811114&travelmode=driving&waypoints=38.9560651%2C-92.3643867%7C38.9532993%2C-92.38365
The maximum number of characters you can submit to an API using a URL is 2,048. Using the shorter latitude/longitude will increase the number of waypoints you can get directions for when using the Google Maps URL.
Having the latitude and longitude also allows me to calculate the distance between two points. All it takes is a little trigonometry. Use your favorite search engine to look for “FileMaker location distance custom function” and you will find several examples of how this can be done.
This is the distance “as the crow flies” and not the driving distance, but if your goal is to perform a search for all addresses within a certain number of miles from a location, this is exactly what you need.
Geocoding is a great API to get started with, it uses the GET method to communicate so it’s easy to set up the URL to submit. Likewise, the data it returns is limited to information about a single address, so there’s not a lot of variability in what you’re going to be getting back. Other APIs in the Google Maps toolbox are considerably more complex.
Distance Matrix Routes API
Before I go on to my next example, I’d like to pause to say a few words about procrastination. Several months ago, when I proposed this article, the plan was to use the Distance Matrix API as my next example. I’ve used it on projects in the past and while it is cumbersome to use if you need to get the distance between multiple points, it makes for an OK example.
As I said, that was several months ago and in between then and now Google released the Routes API, which does everything the Distance Matrix does, only better. I did not feel good about putting out an article with obsolete information in it, but I didn’t have any experience with the new Routes API, so I’ve spent the last few days familiarizing myself with it. Learn from my example everyone. Eat your vegetables, brush your teeth, and get your blogs done when you say you will. If you don’t, they may turn into a lot more work than you planned on.
Now, on to the Routes API.
The Routes API takes an origin point and a destination and returns turn-by-turn driving directions, estimated travel time and the distance between the two points. It also allows you to include intermediate stops between the origin and destination, enabling you to map a multi-stop route.
This can be used to do things like calculate the total driving distance for an employee who makes in-person sales calls with clients. You can even use it to optimize the route. This API has a lot of features and I’d love to show examples of them all, but to avoid blowing another deadline I’ll settle for showing you how to make basic calls and let you take it from there.
Another difference between the Distance Matrix and Routes APIs is that while the Distance Matrix API uses the GET method to send the request, the Routes API uses POST. Using POST means that the parameters are sent in the headers or body of the request rather than in the URL itself. The POST method makes the call to the API more secure and potentially allows more information to be sent in the request, but it comes at a price.
Figuring out how to format POST requests is much more difficult than figuring out how to send a GET. Determining what goes into a header and what goes into the body/payload of the request takes a while and the rules that govern where you should use quotation marks takes some getting used to. It’s a lot like learning to ride a bike. You should go into this expecting to feel awkward and frustrated for a while, but once you finally master it you will be so proud of yourself that you may want to call your mom and yell, “look at me!!” I’m sure she will be impressed.
Documentation for the Routes API can be found here:
https://developers.google.com/maps/documentation/routes/
The minimum parameters you will need to call the Routes API are:
- Origin
- Destination
- API Key
- Field Mask (The list of items you want the API to return. To get them all you can send an ‘*’.)
There are several formats you can use to submit the origin and destination; I’ll be using latitude and longitude. I’m also going to include additional parameters to make sure the data comes back in the format I want. Also, this will make sure you have an example where the payload includes something besides JSON objects:
- Travel Mode
- Language
- Units
Based on Google’s documentation the request to the Routes API should look similar to this:
curl -X POST -d '{
"origin":{
"location":{
"latLng":{
"latitude": 37.419734,
"longitude": -122.0827784
}
}
},
"destination":{
"location":{
"latLng":{
"latitude": 37.417670,
"longitude": -122.079595
}
}
},
"travelMode": "DRIVE",
"languageCode": "en-US",
"units": "IMPERIAL"
}'
-H 'Content-Type: application/json' -H 'X-Goog-Api-Key: YOUR_API_KEY'
-H 'X-Goog-FieldMask: *'
'https://routes.googleapis.com/directions/v2:computeRoutes'
You can probably see where all the parameters fit in the request above, but how do you break it down so you can get them into the Insert from URL script step and send them the Routes API? There are multiple ways this can be done, but in my opinion, the key to success is to build it a piece at a time. When I have JSON objects that contain other JSON objects and I try to build it all at once it usually ends badly.
Let’s look at the Routes Report
script in the example file.
I like to start out by getting all the information I’ll need set into variables:
Then, I take the origin and destination and put them into their own variables. As you can see from the sample request above, the origin and destination are objects that contain a second object (location), which then contain a third (latLng). :
Now, I combine the origin and destination with the other parameters, not including the headers, in another JSON object and put all of that into a variable I call $payload.
Then, I take the method (-X) and the headers (-H), combine these together with the $payload variable created earlier and put it all into a variable I call $cURL.
This, at last, will go into the Insert from URL script step. If you think using all the separate variables seems like a lot of nesting dolls being stacked one inside another, I don’t disagree with you, but this is the approach I’ve found works most reliably. If you are new to this, I’m also hoping this makes it easier to follow along.
You may have noticed I included something in $cURL that doesn’t appear in the example request shown above. The -D $dumpHeader is a curl option that dumps the received header information into the specified FileMaker variable ($dumpHeader). This is handy to use when you want to store the headers an API returns.
For more information about the curl options supported by the Insert from URL script step check out the documentation here:
https://help.claris.com/en/pro-help/content/curl-options.html
When you run this, you will get a LOT of data back. You can cut down on this by modifying the fieldMask parameter. I’ve provided an example of a modified fieldMask step in the Routes Report script and left it commented out so you can review it.
The Routes Report script doesn’t do anything very impressive with the data it gets back from the Routes API, but my goal here was to show how to access the data and let you decide how to use it. You may only want to do something simple with it and display the distance between the origin and the destination, but as you look over the response you get from the API I’m sure you will see that there is much more that can be done here. From building detailed reports, to providing turn-by-turn directions, there are a lot of possibilities. You can also add intermediate stops to the request that will let you map a much more complex route. The sky is the limit.
Embarking on Your Journey
I’ve just scratched the surface on the Google Maps toolbox, but hopefully, this article gives you some ideas about the ways you can use Google Maps to enhance your FileMaker database and provide a more dynamic experience to your users. If you have any questions about what I’ve covered or how to implement it, feel free to reach out to us. We’re here to help.
Built with you in mind
Speak to one of our expert consultants about making sense of your data today. During
this free consultation, we'll address your questions, learn more about your business, and
make some immediate recommendations.