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
Tracey EdlerTracey Edler 

Salespeople mapping customers

Hello:
Any recommendations on free ways salespeople can map their customers easily. I have many requests to put in a zip code and provide a list of customers within a 5-15 mile radius as an example.
 
Thanks!
Joe HayesJoe Hayes
I use something similar to display a list of customers.
It uses SOQL to pull a list of customers and then creates a list of these customers in JSON. This is then passed through the googlemaps api and which returns their co-ordinates. These co-ordinates are then displayed on a map.

My controller:
Public with sharing class GetVenues{
public string locationdata {get;set;}
public GetCustomers(ApexPages.StandardController controller){

List<List<Object>> output = new List<List<Object>>();
for(Account record: [SELECT Name, Id, postal_code__c, latlng__latitude__s, latlng__longitude__s from Account where active__c=True ORDER BY Name]) {
    String customid = String.valueOf(record.Id).substring(0, 15);
    
    output.add(new List<Object> { record.Name, customid, record.postal_code__c, '', ''+record.latlng__latitude__s +','+ record.latlng__longitude__s+'', available});
    
}
locationdata = JSON.serialize(output);
}
}

The page then uses something very close to the standard Google GeoCode api example.
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBXReBjyNDznwS8MUvRGmd3FcHGIxK1-sA&libraries=geometry"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
var locations = {!locationData};

var geocoder = null;
var map = null;
var customerMarker = null;
var gmarkers = [];
var closest = [];

function checkinput(){
if (document.getElementById("address").value.length == 0){ 
   alert("Please enter a postcode or town");
} else {codeAddress(); changeWidth();}
}

function initialize() {
  geocoder = new google.maps.Geocoder();
  map = new google.maps.Map(document.getElementById('map'),
        {
            zoom: 9,
            center: new google.maps.LatLng(54.1934, -3.0941),
            mapTypeControl: false,
            streetViewControl: false,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        });
  var infowindow = new google.maps.InfoWindow();
  var marker, i;
  var bounds = new google.maps.LatLngBounds();
  
  for (i = 0; i < locations.length; i++) {
            var coordStr = locations[i][4];
        var coords = coordStr.split(",");
        var image = {url: 'https://bafecertification.niceic.com/images/mapmarker.png'};
        var pt = new google.maps.LatLng(parseFloat(coords[0]),parseFloat(coords[1]));
            bounds.extend(pt);
            marker = new google.maps.Marker({
                            position: pt,
                            map: map,
                            icon: image,
                            address: locations[i][2],
                            title: locations[i][0],
                            report: locations[i][1],
                            dates: locations[i][5],
                            });
            gmarkers.push(marker);
            google.maps.event.addListener(marker, 'click', (function(marker, i) {         return function() 
            {           infowindow.setContent("<div style = 'width:230px;min-height:25px'><p align='left'><b>" + locations[i][0] + "<br/></b><a style='text-decoration: none;' href='https://eu1.salesforce.com/00OD0000007Asxh?pv0=" + locations[i][1] + "' target='__blank'><b>" + locations[i][5] + "</b></a></p></div>");
                        infowindow.open(map, marker);
            }       
        })
        (marker, i));
    }
    map.fitBounds(bounds);
    
}

      function codeAddress() {
        var numberOfResults = locations.length;
        var address = document.getElementById('address').value;
        geocoder.geocode( { 'address': address + ', UK'}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
        if (customerMarker) customerMarker.setMap(null);
            customerMarker = new google.maps.Marker({
                map: map,
                animation: google.maps.Animation.DROP,
                position: results[0].geometry.location
        });
        map.setZoom(8);
        closest = findClosestN(results[0].geometry.location,numberOfResults);
            // get driving distance
            closest = closest.splice(0,numberOfResults);
            calculateDistances(results[0].geometry.location, closest,numberOfResults);
          } else {
            alert('Cant find postcode...');
          }
        });
      }

function findClosestN(pt,numberOfResults) {
   var closest = [];
   
   for (var i=0; i<gmarkers.length;i++) {
     gmarkers[i].distance = google.maps.geometry.spherical.computeDistanceBetween(pt,gmarkers[i].getPosition());
     
     gmarkers[i].setMap(null);
     closest.push(gmarkers[i]);
   }
   closest.sort(sortByDist);
   return closest;
}

function sortByDist(a,b) {
   return (a.distance- b.distance)
}
     
function calculateDistances(pt,closest,numberOfResults) {
  var service = new google.maps.DistanceMatrixService();
  var request =    {
      origins: [pt],
      destinations: [],
      travelMode: google.maps.TravelMode.DRIVING,
      unitSystem: google.maps.UnitSystem.IMPERIAL,
      avoidHighways: false,
      avoidTolls: false
    };
  for (var i=0; i < 10; i++) {
    request.destinations.push(closest[i].getPosition());
  }
  service.getDistanceMatrix(request, function (response, status) {
    if (status != google.maps.DistanceMatrixStatus.OK) {
      alert('Error was: ' + status);
    } else {
      var origins = response.originAddresses;
      var destinations = response.destinationAddresses;
      var outputDiv = document.getElementById('side_bar');
      outputDiv.innerHTML = '';

      var results = response.rows[0].elements;
      // save title and address in record for sorting
      for (var i=0; i < 10;i++) {
         results[i].title = closest[i].title;
         results[i].address = closest[i].address;
         results[i].report = closest[i].report;
         results[i].dates = closest[i].dates;
     results[i].idx_closestMark = i;
      }
      results.sort(sortByDistDM);
      for (var i = 0; ((i < 10)); i++) {
        closest[i].setMap(map);
        outputDiv.innerHTML +='<div><h3><a href="https://eu1.salesforce.com/' + results[i].report + '" target="__blank" style="text-decoration:none">' + results[i].title + '</h3></div><p style="float: right; margin-top: 0px"><a href="https://eu1.salesforce.com/00OD0000007Asxh?pv0=' + results[i].report + '" target="__blank">' + results[i].dates + '</a></p><br/><img src=".../car.png">&nbsp;'
            + results[i].distance.text + 'les&nbsp;&nbsp;&nbsp;<img src="...clock.jpg">&nbsp;'
            + results[i].duration.text + '<hr width="100%">';
      }
    }
  });
}
function sortByDistDM(a,b) {
   return (a.distance.value- b.distance.value)
}

google.maps.event.addDomListener(window, 'load', initialize);

</script>


 
Khan AnasKhan Anas (Salesforce Developers) 
Hi Tracey,

I trust you are doing very well.

There is an app in app exchange called Map Plotter. For more information on this please refer to this app on AppExchange, it is free.

https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3000000B5P9CEAV


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas
Tracey EdlerTracey Edler
Thanks Khan Anas, I will check it out and let you know