We can get geo locations for the addresses of accounts or leads or contacts in salesforce by making callouts to Google APIs. This can be done in various ways but I will try to explain this with the use of a trigger and a batch class. The batch class will call a class that will make a call out to Google APIs.
Steps are as follows
1) Let’s take a trigger on before update and on Lead object in salesforce
2) The trigger will fire on update and will fire a batch class. This is done so that we are directly not making callouts from triggers.
3) The batch class will take the complete list of leads and will pass the list to a class that will make callouts to google APIs to get geolocation for all leads in the list.
4) The class that will make the call out will be as follows:
public with sharing class GeoCode { static public Cooridinates getAllLocation(Lead theLeadtheLead){ String address = ''; if (theLead.Street != null) { address += theLead.Street +', '; } if (theLead.City != null) { address += theLead.City +', '; } if (theLead.State != null) { address += theLead.State +' '; } if (theLead.PostalCode != null) { address += theLead.PostalCode +', '; } if (theLead.Country != null) { address += theLead.Country; } address = EncodingUtil.urlEncode(address, 'UTF-8'); rrk__Google_API_Setting__c settings = GeoCoder.GetSettings(); Http h = new Http(); HttpRequest req = new HttpRequest(); String baseUri = settings.Base_URL__c; String path = settings.Request_Path__c; String apiKey = settings.API_Key__c; apiKey = apiKey.replace('-', '+').replace('_', '/'); Blob apiKeyBlob = EncodingUtil.base64Decode(apiKey); String clientName = settings.Client_Name__c; String baseRequest = path +'?&address=' + address; Blob urlBlob = Blob.valueOf(baseRequest); String signature = settings.rrk__API_Key__c; //signature = signature.replace('+', '-').replace('/', '_'); req.setEndpoint(baseUri + baseRequest + '&key=' + signature); req.setMethod('GET'); req.setTimeout(60000); HttpResponse res = h.send(req); system.debug('res.getStatusCode()::'+res.getStatusCode()); if(res.getStatusCode() == 200) { JSONParser parser = JSON.createParser(res.getBody()); system.debug('response::'+res.getBody()); double lat = null; double lon = null; while (parser.nextToken() != null) { if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'location')) { parser.nextToken(); while (parser.nextToken() != JSONToken.END_OBJECT) { String txt = parser.getText(); parser.nextToken(); if(txt == 'lat') { lat = parser.getDoubleValue(); } else if(txt == 'lng') { lon = parser.getDoubleValue(); } } } } return new Cooridinates(lat, lon); } else { return null; } } private static rrk__Google_API_Setting__c GetSettings() { return rrk__Google_API_Setting__c.getOrgDefaults(); } public class Cooridinates { public Double Lat {get; private set;} public Double Lon {get; private set;} public Cooridinates(Double newLat, Double newLong) { this.Lat = newLat; this.Lon = newLong; } } }
Here I have first created a custom setting named rrk__Google_API_Setting__c where I have saved certain values that will be dynamically used in the code for example
*) API Key*) Base URL*) Client Name*) Request Path
If we are using the standard edition for API Callouts to google then need to use the API KEY in the endpoint URL and the endpoint URL will be like:
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY
If we are using the premium version for API Callouts to google then we need to use Client Id as an added parameter in the endpoint URL. The URL will be as:
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&client=YOUR_CLIENT_ID&signature=SIGNATURE
This will get geolocation as a response from google API, we can then use JSON and fetch the geolocation with two parameters: Latitude And Longitude.