function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
pixelriesepixelriese 

Calculate the exact distance between a lead and an list of accounts.

Hello, i have the problem that i would like to calucute exact distance between a lead and a list of accounts. I'm currently use a visual force page with a map component and i am use a standard function distance() to calculate the distance. Has someone an idea how to solve this issue? I would like to use a JavaScript-FrameWork or google Maps API. 
Shruti VishShruti Vish
Hi pixelriese

This below code will work.As here me calculating distance between source and destination using javscript.You try out the below code


<apex:page >
    <style>
    span, input {
    margin: 5px;
    padding-right:10px;
   
}
    </style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>

<script type="text/javascript">
var source, destination;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
  var geocoder = new google.maps.Geocoder();
google.maps.event.addDomListener(window, 'load', function () {
    new google.maps.places.SearchBox(document.getElementById('txtSource'));
    new google.maps.places.SearchBox(document.getElementById('txtDestination'));
    directionsDisplay = new google.maps.DirectionsRenderer({ 'draggable': true });
    
});
 
function GetRoute() {
    
    var india = new google.maps.LatLng(20.5937, 78.9629);
    var mapOptions = {
        zoom: 7,
        center: india
    };
    map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById('dvPanel'));
 
    //*********DIRECTIONS AND ROUTE**********************//
    source = document.getElementById("txtSource").value;
    destination = document.getElementById("txtDestination").value;
   
 
    var request = {
        origin: source,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
        }
    });
 
    //*********DISTANCE AND DURATION**********************//
    var service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix({
        origins: [source],
        destinations: [destination],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, function (response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK && response.rows[0].elements[0].status != "ZERO_RESULTS") {
            var distance = response.rows[0].elements[0].distance.text;
            var duration = response.rows[0].elements[0].duration.text;
            var dvDistance = document.getElementById("dvDistance");
           dvDistance.innerHTML = "";
            dvDistance.innerHTML += "Distance: " + distance + "<br />";
            dvDistance.innerHTML += "Duration:" + duration;
 
        } else {
            alert("Unable to find the distance via road.");
        }
    });
    }
    
    function GetLocation() {
          
            var address = document.getElementById("txtSource").value;
            geocoder.geocode({ 'address': address }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    var latitude = results[0].geometry.location.lat();
                    var longitude = results[0].geometry.location.lng();
                    document.getElementById("latitude1").value=latitude;
                    document.getElementById("longitude1").value=longitude;
                    alert("Latitude: " + latitude + "\nLongitude: " + longitude);
                } else {
                    alert("Request failed.")
                }
            });
        };
    function GetLocation1() {
          
            var address = document.getElementById("txtDestination").value;
            geocoder.geocode({ 'address': address }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    var latitude = results[0].geometry.location.lat();
                    var longitude = results[0].geometry.location.lng();
                    document.getElementById("latitude2").value=latitude;
                    document.getElementById("longitude2").value=longitude;
                    alert("Latitude: " + latitude + "\nLongitude: " + longitude);
                } else {
                    alert("Request failed.")
                }
            });
        };
</script>
         
   <table border="0" cellpadding="0" cellspacing="3">
<tr>
    <td colspan="3">
        Source  &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp; &nbsp;  &nbsp; &nbsp;  &nbsp; 
        <input  type="text" id="txtSource" value="" style="width: 200px"  onChange="GetLocation();"/>
        &nbsp; &nbsp;
               
         &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;Destination
        <input type="text" id="txtDestination" value="" style="width: 200px"  onChange="GetLocation1();"/>
       
       
        <input type="button" value="Get Route" onclick="GetRoute()" />
        <hr />
    </td>
</tr>
<tr>
    <td colspan="2">
        <div id="dvDistance">
        </div>
    </td>
</tr>
<tr>
    <td>
        <div id="dvMap" style="width: 500px; height: 200px">
        </div>
    </td>
   <!-- <td>
        <div id="dvPanel" style="width: 200px; height: 200px">
        </div>
    </td> -->
</tr>
</table>
        
</apex:page>

If you get solved with issues please mark it as best answer So others can use it
pixelriesepixelriese
Thank you for this code. I alread have a table and i would like to display the route there. Alternatively it could also be a Button. here is me code: 
<apex:page standardController="Lead" extensions="ldControllerV2">
    
    <apex:form >
        <apex:pageBlock title="Partner in der Umgebung">
       
          
            <apex:panelGrid columns="2">
           <apex:pageBlockSection >
                <apex:pageBlockSection title="Potenzieller Kunde" >

                  <apex:outputLabel value="{!$ObjectType.Lead.Fields.Name.label}" />{!Lead.Salutation} {!Lead.name} <br />
                  <apex:outputLabel value="{!$ObjectType.Lead.Fields.Address.label}" /> 
                  {!Lead.Street} <br />
                  {!Lead.City} <br />
                   {!Lead.PostalCode} <br />
                <apex:outputLabel value="{!$ObjectType.Lead.Fields.Phone.label}" />{!Lead.Phone} <br />
                <apex:outputLabel value="{!$ObjectType.Lead.Fields.EnergySource__c.label}" />{!Lead.EnergySource__c} <br />
         
    
                
                </apex:pageBlockSection>
              
              
   <apex:pageBlockSection title="Partner-Map">
     <!-- Display the address on a map -->
 <apex:map width="600px" height="400px" mapType="roadmap" zoomLevel="11" center="{!Lead.Street},{!Lead.City},{!Lead.State}" rendered="true">
  <apex:mapMarker title="{!Lead.Name} " icon="{!URLFOR($Resource.UserIcon)}" position="{latitude:{!Lead.Latitude}, longitude:{!Lead.Longitude}}"></apex:mapMarker>    
  <apex:repeat value="{!accounts }" var="a">
      <apex:mapMarker title="{!a.Name} - {!a.Skills__c}" position="{latitude:{!a.ShippingLatitude},longitude:{!a.ShippingLongitude}}"/>
  </apex:repeat>     
 </apex:map>
     </apex:pageBlockSection>
            </apex:pageBlockSection>
                </apex:panelGrid>
                   

             <apex:pageBlockSection title="Partner nach Entfernung" id="results" columns="1" >
                 
                           
                 
            <apex:pageBlockTable value="{!accounts}" var="a" width="200%" >
             <apex:column value="{!distances[a.id]}"> <apex:facet name="header">Entfernung</apex:facet></apex:column>
            <apex:column value="{!a.Priority__c}"/>
                <apex:column value="{!a.name}"/>    
         
            <apex:column value="{!a.ShippingStreet}"/>
            <apex:column value="{!a.ShippingCity}"/>
                 <apex:column value="{!a.phone}"/>
               
            <apex:column value="{!a.Skills__c}"/> 
               
                
               
                

            <apex:column >
                <apex:commandLink title="Zuordnen" value="Zuordnen" action="{!processButtonClick}">
             <apex:param name="heatingInstallerID" value="{!a.id}"/>
                </apex:commandLink>
                </apex:column>
             
            </apex:pageBlockTable>
        </apex:pageBlockSection>
         
            
    </apex:pageBlock>
    </apex:form>
</apex:page>
 
public class ldControllerV2 {
    
    //Lead-Informationen
    public Lead leadRecord{get;set;}
    Decimal leadLatitude ;
    Decimal leadLongitude ;
    
    //Account-Informationen
    public List<Account> acc {get;set;}
    String[] skills{get;set;}
    
    //Condition for a Method
    boolean hasCondition = false;
    
    //Map with Distances
   public Map<String, String> distances{get;set;}
    
    
    //String with Queries 
    String query = 'SELECT Id, Name, ShippingLatitude, ShippingLongitude, ShippingAddress, ShippingStreet, ShippingCity, ShippingState, Phone, Skills__c, Priority__c FROM Account WHERE RecordTypeId=\'01258000000ATCX\' AND ShippingLatitude!=null AND Priority__c !=null' ;
    String recordId = '01258000000ATCX';
  
    //Constructor, assign a List of Accounts, Distances and imports the lead account
    public ldControllerV2(ApexPages.StandardController sc)
    {
        
        acc = new List<Account>();
        this.leadRecord = (Lead) sc.getRecord();        
        this.distances = new Map<String, String>();

       
        if(leadRecord.id != null && leadRecord!=null)
        {
            leadRecord = [select Name,Latitude,Longitude, EnergySource__c from lead where id =:leadRecord.id ];
            leadLatitude  = leadRecord.Latitude;
            leadLongitude = leadRecord.Longitude;
            skills = leadRecord.EnergySource__c.split(';');
        }
    }
    
    public List<Account> getAccounts(){

        //'GEOLOCATION(' + leadLatitude + ', ' + leadLongitude + '), ' +
       
        if(!skills.isEmpty())
      {
            hasCondition =true;
            query += ' AND Skills__c includes (\''+skills[0]+'\'';
      skills.remove(0);
        }
        while(!skills.isEmpty()){
            query +=',\''+skills[0]+'\'';
            skills.remove(0);
        }
    
      if(hasCondition) query +=')';
        hasCondition = false;
      
        Acc = Database.query(query+
                             ' ORDER BY DISTANCE(ShippingAddress, GEOLOCATION(' + leadLatitude + ', ' + leadLongitude + '), \'km\') '+
                             'limit 20');   
        resolveDistances();
        
        return Acc;
    }
    
    
     public PageReference processButtonClick() {
        
    ID heatingInstallerID = System.currentPageReference().getParameters().get('heatingInstallerID');
        leadRecord.ZH_Account__c = heatingInstallerID;
         
         update leadRecord;
         PageReference pg = new PageReference('/'+ leadRecord.Id);
        pg.setRedirect(true);
        return pg;
         
    }
    
    
    public void resolveDistances(){
        
        for(Account a : acc) {
      
            Location accLoc = Location.newInstance(a.ShippingLatitude, a.ShippingLongitude);
            Location leadLoc = Location.newInstance(leadRecord.Latitude, leadRecord.Longitude);
            Integer distance = (Integer) accLoc.getDistance(leadLoc, 'km');
            String km = distance+' km';
            
            this.distances.put(a.ID, km);
        }
        
    }

    public void resolveDistance(Account a){
    
    
    }
    
    
}