I’m new to SalesForce and I’m working on an app that requires me to calculate distance between two given addresses.
User enters 2 addresses and then I calculate the distance between those two addresses. I can use Google Map API and get this done, but I don’t know how to use it.
Can someone help me on this? I’ve looked through a lot of threads and they are too old or too complex.
Or, can some one at least guide me to something that might help?
If I have the longitude and latitude of the location, then I can find distance using “Geolocation” function. But, how do I get the longitude and latitude?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
As of Summer ’16, you can take advantage of platform supported geolocation for certain standard fields.
These fields are:
BillingAddress
on AccountsShippingAddress
on AccountsMailingAddress
on ContactsAddress
on Leads
You can read more on Set up Geocode Clean Rules.
An example from the provided documentation:
You add an account with a value of
One Market Street, San Francisco, CA 94105-5188, United States
for theBilling Address
field. When you save this account, values for theBillingLatitude
,BillingLongitude
, andBillingGeocodeAccuracy
fields are added.
37.793819
toBillingLatitude
-122.395089
toBillingLongitude
Address
toBillingGeocodeAccuracy
Available in: Professional, Enterprise, Performance, Unlimited, and Developer Editions
Credit to this answer goes to @MarkPond for mentioning it in the comments.
Method 2
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; } }
Method 3
Using the Google Maps Geocoding API
is what you need. Just go to console.developers.google.com to get an API key. They allow you 2500 requests a day for free.
Apex Code Snippet
@TestVisible private static String buildAddress(Account account) { String address = ''; if (account.BillingStreet != null) address += account.BillingStreet +', '; if (account.BillingCity != null) address += account.BillingCity +', '; if (account.BillingState != null) address += account.BillingState +' '; if (account.BillingPostalCode != null) address += account.BillingPostalCode +', '; if (account.BillingCountry != null) address += account.BillingCountry; address = EncodingUtil.urlEncode(address, 'UTF-8'); return address; } @TestVisible private static HttpRequest buildWebServiceRequest(String address) { HttpRequest request = new HttpRequest(); request.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&key=' + key); request.setMethod('GET'); request.setTimeout(60000); return request; } @TestVisible private static void handleResponse(HttpResponse response, Account account) { double lat; double lng; JSONParser parser = JSON.createParser(response.getBody()); while (parser.nextToken() != null) { if (parser.getCurrentToken() == JSONToken.FIELD_NAME && parser.getText() == 'location') { parser.nextToken(); while (parser.nextToken() != JSONToken.END_OBJECT) { String text = parser.getText(); if (text.equals('lat')) { parser.nextToken(); lat = parser.getDoubleValue(); } if (text.equals('lng')) { parser.nextToken(); lng = parser.getDoubleValue(); } } } } account.Main_Office_Geolocation__Latitude__s = lat; account.Main_Office_Geolocation__Longitude__s = lng; }
EDIT
After reading another post from today this code needs to give some credit to the original author. I didn’t find the snippets from there, but it seems that is where it most likely originated from. Possibly who originally Authored the code
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0