I've got a function I used in an older project which does exactly this, using some custom settings to store the API Keys used for the transactions. This example does require you to have a valid Google Maps API Key, which you can get from their site. Be aware that you do run the risk of going over the provided limits with a free account, and if you need to have a large number of users providing information, you may have to upgrade. You can read more about the limits (Which I would add to this post, but they are subject to change) here.
Once you obtain your keys, I highly recommend placing them in a Custom Setting, and using that in your code to manage any future changes, as well as to prevent it from being hard coded in a number of files, if you ever need it in multiple locations. You can also use the setting to store additional configuration information (In my case, I was using it to store callback information to generate a json file).
This code uses the Http
and HttpRequest
classes, and constrcuts a request url based on Google Documentation. It uses the Google_API_Key__c
custom setting field, which pulls in the valid key, and adds it to the request. This code specifies a json request from the geocoding api, but this can be modified.
public class GoogleAPI_Handler {
// Example url construction
// 'https://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&key=' + key
public static Map<String, Object> Request(String address) {
Http http = new Http();
HttpRequest request = new HttpRequest();
MEP_MapSettings__c d = MEP_MapSettings__c.getInstance('Default');
// Can only request a single address at a time
String endpoint = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + address;
endpoint += '&key=' + d.Google_API_Key__c;
request.setEndpoint(endpoint.replace(' ', '+')); // Remove spaces in addresses
request.setMethod('GET');
HttpResponse response = http.send(request);
Map<String, Object> resultJSON = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
if ((String)resultJSON.get('status') != 'OK') {
// Log/Handle error
} else {
List<Object> apiResult = (List<Object>)resultJSON.get('results');
Object actualResult = (Object)apiResult[0]; // Gets the 'address_components' section from the result
Map<String, Object> returnMap = new Map<String, Object>();
Map<String, Object> actualResultMap = (Map<String, Object>)actualResult; // Cast to Map to work with
Map<String, Object> geo = (Map<String, Object>)actualResultMap.get('geometry'); // Move into geometry section- contains location data needed
Map<String, Object> coords = (Map<String, Object>)geo.get('location'); // Contains exact location information
returnMap.put('lng', coords.get('lng'));
returnMap.put('lat', coords.get('lat'));
returnMap.put('formatted_address', actualResultMap.get('formatted_address'));
return returnMap;
}
return null;
}
}