title: Google Maps API - Closest points - Changing the sort order
body: <p>I have a number of employees in various locations.  When I receive a job, I want to assign it to the nearest employee. So in this case, the assignment is in zip code 06810.  The current code below first ranks the straight line distance using Latitude and Longitude. Then using google directions, the actual driving distance in miles is calculated but is still sorted by straight line distance.  I would like the results sorted by actual driving distance like in the second group.  Anyone know how to do this?  Thanks</p>
  
  <pre><code>Original Results - http://vince.netau.net/vince.html    Using Zip Code 06810
  Jen Alexander process 3:41.159977,-73.982356:      50348.52      54.3 Miles
  Richard Henderson process 11:40.858696,-73.297249: 59009.38        92 Miles
  Jim Thomas process 0:41.041599,-74.019554:         60252.91      55.5 Miles
  Don James process 2:40.997704,-74.050598:          65365.08      59.5 Miles
  John Smith process 1:40.986584,-74.290207:         82405.22        74 Miles
  Al Bundy process 8:40.804319,-74.122668:           84834.76      71.2 Miles
  Tim Hager process 7:40.691845,-73.969104:          87569.35      69.9 Miles
  Ken Roberts process 5:40.754302,-74.409713:       105950.12      92.8 Miles
  Vince Patera process 9:40.562019,-74.452335:      123497.86       101 Miles
  Thomas Glenn process 10:40.291759,-74.343231:     142031.60       109 Miles
  Tom Jones process 4:40.001475,-75.0268:           202567.94       153 Miles
  Kevin James process 6:39.82534,-74.919937:        212467.19       155 Miles
  
  Results I want
  Jen Alexander process 3:41.159977,-73.982356:      50348.52      54.3 Miles
  Jim Thomas process 0:41.041599,-74.019554:         60252.91      55.5 Miles
  Don James process 2:40.997704,-74.050598:          65365.08      59.5 Miles
  Tim Hager process 7:40.691845,-73.969104:          87569.35      69.9 Miles
  Al Bundy process 8:40.804319,-74.122668:           84834.76      71.2 Miles
  John Smith process 1:40.986584,-74.290207:         82405.22        74 Miles  
  Richard Henderson process 11:40.858696,-73.297249: 59009.38        92 Miles
  Ken Roberts process 5:40.754302,-74.409713:       105950.12      92.8 Miles
  Vince Patera process 9:40.562019,-74.452335:      123497.86       101 Miles
  Thomas Glenn process 10:40.291759,-74.343231:     142031.60       109 Miles
  Tom Jones process 4:40.001475,-75.0268:           202567.94       153 Miles
  Kevin James process 6:39.82534,-74.919937:        212467.19       155 Miles
  </code></pre>
  
  <p>code: </p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
   &lt;html&gt;
     &lt;head&gt;
       &lt;title&gt;Google Maps JavaScript API v3 Example: Map Simple&lt;/title&gt;
       &lt;meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"&gt;
       &lt;meta charset="utf-8"&gt;
       &lt;style&gt;
         html, body, #map_canvas {
           margin: 0;
           padding: 0;
           height: 100%;
         }
       &lt;/style&gt;
  &lt;script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&amp;sensor=false"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;     
  // Store Name[0],delivery[1],Address[2],Delivery Zone[3],Coordinates[4] data from FusionTables pizza stores example
  var locations = [
  ["Jim Thomas","no","12 Williams Rd, Montvale, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.121277,37.386799,0 -122.158012,37.4168,0 -122.158012,37.448151,0 -122.142906,37.456055,0 -122.118874,37.45224,0 -122.107544,37.437793,0 -122.102737,37.422526,0 -122.113037,37.414618,0 -122.121277,37.386799,0   &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","41.041599,-74.019554","http://maps.google.com/mapfiles/ms/icons/blue.png"],
  ["John Smith","yes","8 Craig Place, Pompton Lakes, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.200928,37.438611,0 -122.158012,37.4168,0 -122.158012,37.448151,0 -122.142906,37.456055,0 -122.144623,37.475948,0 -122.164192,37.481125,0 -122.189255,37.478673,0 -122.208481,37.468319,0 -122.201271,37.438338,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.986584,-74.290207","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Don James","no","689 Fern St, Township of Washington, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.304268,37.516534,0 -122.300835,37.505096,0 -122.262383,37.481669,0 -122.242813,37.502917,0 -122.244186,37.534232,0 -122.269249,37.550021,0 -122.291222,37.545122,0 -122.302895,37.537499,0 -122.304268,37.516534,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.997704,-74.050598","http://maps.google.com/mapfiles/ms/icons/red.png"],
  ["Jen Alexander","yes","45 Heritage Dr, New City, NY","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.304268,37.516534,0 -122.348557,37.538044,0 -122.359886,37.56363,0 -122.364006,37.582405,0 -122.33654,37.589207,0 -122.281609,37.570433,0 -122.291222,37.545122,0 -122.302895,37.537499,0 -122.304268,37.516534,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","41.159977,-73.982356","http://maps.google.com/mapfiles/ms/icons/yellow.png"],
  ["Tom Jones","yes","263 W. Broad St, Palmyra, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.374306,37.548933,0 -122.348557,37.538044,0 -122.359886,37.56363,0 -122.364006,37.582405,0 -122.33654,37.589207,0 -122.359543,37.59764,0 -122.372246,37.604712,0 -122.417564,37.594648,0 -122.374306,37.548933,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.001475, -75.026800","http://maps.google.com/mapfiles/ms/icons/blue.png"],
  ["Ken Roberts","yes","169 Main St, Madison, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.462883,37.628916,0 -122.445374,37.639247,0 -122.426147,37.648762,0 -122.405205,37.642238,0 -122.400055,37.628644,0 -122.392159,37.610696,0 -122.372246,37.604712,0 -122.417564,37.594648,0 -122.462196,37.628644,0  &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.754302, -74.409713","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Kevin James","yes","90 Tenby Chase Dr, Voorhees, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.43576,37.790795,0 -122.449493,37.801646,0 -122.425461,37.809784,0 -122.402115,37.811411,0 -122.390442,37.794593,0 -122.408295,37.79188,0 -122.434387,37.789167,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","39.825340, -74.919937","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Tim Hager","yes","208 Clinton Ave, Brooklyn, NY","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.463398,37.760266,0 -122.477349,37.774785,0 -122.427349,37.774785,0 -122.429237,37.763658,0 -122.46357,37.760808,0&lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.691845, -73.969104","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Al Bundy","yes","554 Page Ave, Lyndhurst, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.418766,37.747779,0 -122.425289,37.768951,0 -122.406063,37.769901,0 -122.406063,37.749679,0 -122.418251,37.747508,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.804319, -74.122668","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Vince Patera","yes","12 Marissa Ct, Piscataway, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.121277,37.386799,0 -122.108917,37.362244,0 -122.077675,37.3385,0 -122.064285,37.378615,0 -122.069778,37.3898,0 -122.076645,37.402619,0 -122.078705,37.411619,0 -122.113037,37.414618,0 -122.121277,37.386799,0  &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.562019, -74.452335","http://maps.google.com/mapfiles/ms/icons/green.png"],
  ["Thomas Glenn","no","8 Taylors Mills Rd, Manalapan, NJ","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-122.047119,37.33113,0 -122.065315,37.332495,0 -122.077675,37.3385,0 -122.064285,37.378615,0 -122.036819,37.385162,0 -122.006607,37.382162,0 -122.00386,37.342048,0 -122.047119,37.331403,0  &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.291759, -74.343231","http://maps.google.com/mapfiles/ms/icons/blue.png"],
  ["Richard Henderson","no","27 Buhl Ln, East Northport, NY","&lt;Polygon&gt;&lt;outerBoundaryIs&gt;&lt;LinearRing&gt;&lt;coordinates&gt;-121.935196,37.345051,0 -121.931076,37.294267,0 -121.871338,37.293721,0 -121.806793,37.293174,0 -121.798553,37.361426,0 -121.879578,37.36088,0 -121.934509,37.345597,0 -121.935196,37.345051,0 &lt;/coordinates&gt;&lt;/LinearRing&gt;&lt;/outerBoundaryIs&gt;&lt;/Polygon&gt;","40.858696, -73.297249","http://maps.google.com/mapfiles/ms/icons/yellow.png"],
  ];
  // alert(locations.length);
  
  var geocoder = null;
  var map = null;
  var customerMarker = null;
  var gmarkers = [];
  var closest = [];
  var directionsDisplay = new google.maps.DirectionsRenderer();;
  var directionsService = new google.maps.DirectionsService();
  var map;
  
  function initialize() {
  // alert("init");
    geocoder = new google.maps.Geocoder();
    map = new google.maps.Map(document.getElementById('map'), 
          {       
              zoom: 9,       
              center: new google.maps.LatLng(52.6699927, -0.7274620),       
              mapTypeId: google.maps.MapTypeId.ROADMAP     
          });      
    var infowindow = new google.maps.InfoWindow();      
    var marker, i;      
    var bounds = new google.maps.LatLngBounds();
    document.getElementById('info').innerHTML = "found "+locations.length+" locations&lt;br&gt;";
    for (i = 0; i &lt; locations.length; i++) {         
              var coordStr = locations[i][4];
          var coords = coordStr.split(",");
          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: locations[i][5],
                              address: locations[i][2],
                              title: locations[i][0],
                              html: locations[i][0]+"&lt;br&gt;"+locations[i][2]+"&lt;br&gt;&lt;br&gt;&lt;a href='javascript:getDirections(customerMarker.getPosition(),&amp;quot;"+locations[i][2]+"&amp;quot;);'&gt;Get Directions&lt;/a&gt;"
                              });                              
              gmarkers.push(marker);
              google.maps.event.addListener(marker, 'click', (function(marker, i) {         return function() 
              {           infowindow.setContent(marker.html);
                          infowindow.open(map, marker);         
              }       
          })
          (marker, i));     
      }
      map.fitBounds(bounds);   
  
  }
  
        function codeAddress() {
          var address = document.getElementById('address').value;
          geocoder.geocode( { 'address': address}, 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,
                  position: results[0].geometry.location
              });
          closest = findClosestN(results[0].geometry.location,12);
              // get driving distance
              closest = closest.splice(0,12);
              calculateDistances(results[0].geometry.location, closest,12);
            } else {
              alert('Geocode was not successful for the following reason: ' + status);
            }
          });
        }
  
  function findClosestN(pt,numberOfResults) {
     var closest = [];
     document.getElementById('info').innerHTML += "processing "+gmarkers.length+"&lt;br&gt;";
     for (var i=0; i&lt;gmarkers.length;i++) {
       gmarkers[i].distance = google.maps.geometry.spherical.computeDistanceBetween(pt,gmarkers[i].getPosition());
       document.getElementById('info').innerHTML += "process "+i+":"+gmarkers[i].getPosition().toUrlValue(6)+":"+gmarkers[i].distance.toFixed(2)+"&lt;br&gt;";
       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&lt;closest.length; 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;
        for (var i = 0; i &lt; numberOfResults; i++) {
          closest[i].setMap(map);
          outputDiv.innerHTML += "&lt;a href='javascript:google.maps.event.trigger(closest["+i+"],\"click\");'&gt;"+closest[i].title + '&lt;/a&gt;&lt;br&gt;' + closest[i].address+"&lt;br&gt;"
              + results[i].distance.text + ' appoximately '
              + results[i].duration.text + '&lt;br&gt;&lt;hr&gt;';
        }
      }
    });
  }
  
  function getDirections(origin, destination) {
    var request = {
        origin:origin,
        destination:destination,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setMap(map);
        directionsDisplay.setDirections(response);
        directionsDisplay.setPanel(document.getElementById('side_bar'));
      }
    });
  }
  
  google.maps.event.addDomListener(window, 'load', initialize);
  &lt;/script&gt; 
     &lt;/head&gt;
     &lt;body&gt;
  &lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;
       &lt;div id="map" style="height: 600px; width:800px;"&gt;&lt;/div&gt;
  &lt;/td&gt;&lt;td&gt;
       &lt;div id="side_bar"&gt;&lt;/div&gt;
  &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
  &lt;input id="address" type="text" value="Palo Alto, CA"&gt;&lt;/input&gt;
  &lt;input type="button" value="Search" onclick="codeAddress();"&gt;&lt;/input&gt;
  &lt;div id="info"&gt;&lt;/div&gt;
     &lt;/body&gt;
   &lt;/html&gt;
  </code></pre>