This is Part 3 in a multi-part series about using the location functions in FileMaker Go.
In previous posts, we explored how the Location and LocationValues functions in FileMaker Go can get the current geographic coordinates of your iOS devices. Only knowing your current latitude and longitude doesn’t accomplish much for you if you don’t also know where other points of interest are. Where’s home? Where’s work? Where’s your next worksite? Where has The Doctor hidden his latest clue?
We don’t normally think of these locations in terms of geographic coordinates. When was the last time you told someone anything along the lines of, “Our office is at 34.755132 North, 82.268789 West”? Most of us usually communicate in terms of addresses instead: “Our office is at 10017 Pelham Road, Simpsonville, South Carolina.” If you want to know where you and your iPhone are relative to an address, you have to convert that address to latitude and longitude first.
This is what geocoding is for. You send an address to your geocoding service of choice, and the service returns that address’s coordinates. It isn’t a perfect science, but it’s pretty good. There are several services available, but I’ll stick with Google’s Geocoding API for now. Just format a URL with an address, and the API returns a chunk of text containing the geographic coordinates of the address. Here’s what the calculation for the URL looks like:
"https://maps.googleapis.com/maps/api/geocode/json?address=" & GetAsURLEncoded ( $address ) & "&sensor=" & If ( Get ( SystemPlatform ) = 3 ; // only iOS devices have location sensors "true" ; /* Else */ "false" )
Now that we have a URL, we can get a response from the API using the Insert from URL script step.
Once the API sends its response, the Insert From URL step puts the result in the target field. Google’s Geocoding API can send its response in JSON or XML format, depending on what URL you use to make your request. I chose to request the JSON format.
Dan Smith wrote a FileMaker module that parses JSON into Let Notation, another data format that’s easier to work with in FileMaker. Let Notation is especially easy to work with using the #-Parameter family of custom functions. Once I have the API’s JSON response converted to Let Notation, it’s a piece of cake to traverse the data structure and extract the latitude and longitude.
One great thing about Google’s Geocoding API is that it not only returns the geographic coordinates for an address, but it also parses the address into separate components and tries to fill-in any blanks it can — you get an address data cleaning service for free! In the example file for this blog post, the postal code data is missing from all the addresses; but that data can be filled-in using the API responses.
Unlike the Location and LocationValues functions, you don’t have to be running FileMaker Go on an iPhone or iPad to use geocoding. If you want, you can gather coordinates for many addresses in FileMaker Pro on a desktop computer and later transfer that data to your iOS devices for quick reference.
Geocoding is good for getting latitude and longitude for an address, but what about the other way around? Reverse geocoding is the process of taking a pair of geographic coordinates and finding the address at that location. This is good for situations where you find yourself in the field with FileMaker Go wondering, “What’s the address here?” Once you have a position from the Location or LocationValues functions, you can pass that to a reverse geocoding service to get the address at that location.
Reverse geocoding with Google’s Geocoding API is very similar to “forward” geocoding: build a request in the form of a URL, ask the reverse geocoding service for an address, and parse the result. The URL I used looks like this:
"https://maps.googleapis.com/maps/api/geocode/json?latlng=" & $latitude & "," & $longitude & "&sensor=" & If ( Get ( SystemPlatform ) = 3 ; // only iOS devices have location sensors "true" ; /* Else */ "false" )
The data parsing is similar. Convert the JSON to Let Notation, then extract the address field values from the result.
If you’re not comfortable re-implementing any of the code you see in this post, or if you’re just lazy, feel free to copy mine: Location.fmp12