3

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?

10
  • 1
    You'll likely need an external API for that, such as Google Maps. Once you picked one, you need to use API calls to geocode the addresses. Commented Jul 22, 2016 at 16:48
  • 1
    If those external APIs are acceptable to you, I can add an answer with some example code on calling them, and updating fields. Commented Jul 22, 2016 at 16:55
  • 2
    This question should really just be posted on Stack Overflow, but it sounds like @battery.cord is helping you out, so I won't flag to close...yet.
    – Adrian Larson
    Commented Jul 22, 2016 at 17:05
  • 3
    Geolocation on-platform was made available in Summer '16 for the standard address fields using data.com clean rules. Details here in the Release Notes.
    – Mark Pond
    Commented Jul 22, 2016 at 18:01
  • 3
    ^ If your addresses fall onto those Standard fields. And that should be an answer as well. Commented Jul 22, 2016 at 18:04

3 Answers 3

2

As of Summer '16, you can take advantage of platform supported geolocation for certain standard fields.

These fields are:

  1. BillingAddress on Accounts
  2. ShippingAddress on Accounts
  3. MailingAddress on Contacts
  4. Address 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 the Billing Address field. When you save this account, values for the BillingLatitude, BillingLongitude, and BillingGeocodeAccuracy fields are added.

  • 37.793819 to BillingLatitude
  • -122.395089 to BillingLongitude
  • Address to BillingGeocodeAccuracy

Available in: Professional, Enterprise, Performance, Unlimited, and Developer Editions


Credit to this answer goes to @MarkPond for mentioning it in the comments.

2
  • already got it with clean rules. working just fine. thanks guys!
    – Anony-Kun
    Commented Jul 26, 2016 at 17:43
  • The URL you posted is not working anymore, looks like they started deprecating this topic, did anyone managed to make those rules work lately? Commented Mar 2, 2023 at 10:28
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).

Google_API_Key__c

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;
    }
}
1
  • I'll be editing a few sections in this snippet (notably the Object actualResult = (Object)apiResult[0]; line) for clarity. Commented Jul 22, 2016 at 18:21
1

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

1
  • Damn, the "authored" link did the job! Thanks a LOT!
    – Anony-Kun
    Commented Jul 23, 2016 at 15:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .