Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

google maps api v3 how to rank by closest distance

Does anyone know how to use the rank by distance search option that is mentioned here? https://developers.google.com/maps/documentation/javascript/places#place_search_requests

Listing this in the request options doesn't seem to work. Here's my portion of code relative to this:

var request = {
  location: coords,
  //radius: 30000,
  keyword: ['puma, retail'],
  types: ['store'],
  rankBy: google.maps.places.RankBy.DISTANCE
};

service = new google.maps.places.PlacesService(map);
service.search(request, callback);

function callback(results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
                            listResults(results[i]);
        }
    } 
}

Code will locate and list results if I include a radius, but the results aren't listed in ascending order by distance. Google's docs say a radius isn't necessary either if using the rankBy option. Am I missing something?

like image 352
JFlo Avatar asked May 23 '12 19:05

JFlo


People also ask

How does a Distance Matrix API work?

The Distance Matrix API provides travel distance and time for a matrix of origins and destinations, and consists of rows containing duration and distance values for each pair. Distance Matrix is available in several forms: as a standalone API. as part of the client-side Maps JavaScript API.

Is Google Distance Matrix API free?

The Distance Matrix API uses a pay-as-you-go pricing model.


2 Answers

You cannot use radius and RankBy.DISTANCE properties together. Therefore you have two options:

1) Search by radius then sort the results by distance in your own code.

Example:

var request = {
               location: coords,
               radius: 30000,
               keyword: ['puma, retail'],
               types: ['store']
               };
service = new google.maps.places.PlacesService(map);
service.search(request, callback);

function callback(results, status) {
         if (status == google.maps.places.PlacesServiceStatus.OK) {
          for (var i = 0; i < results.length; i++) {
           sortresults(results[i]);//sortresult uses haversine to calcuate distance and then arranges the result in the order of distance
           createMarker(results[i]);
           listResults(results[i]);
       }
   } 
}

Option 2: Search by RankBy.Distance then cap the result using the radius. Again you would need haversine formula to calculate distances.

var request = {
               location: coords,
               rankBy: google.maps.places.RankBy.DISTANCE,
               keyword: ['puma, retail'],
               types: ['store']
               };
service = new google.maps.places.PlacesService(map);
service.search(request, callback);

function callback(results, status) {
         if (status == google.maps.places.PlacesServiceStatus.OK) {

           for (var i = 0; i < results.length; i++) {
           d= distance(coords,results[i].latlng)
           if(d<rd)
            {createMarker(results[i]);
             listResults(results[i]);
            }
           }
   } 
}

//Returns Distance between two latlng objects using haversine formula
distance(p1, p2) {
 if (!p1 || !p2) 
  return 0;
 var R = 6371000; // Radius of the Earth in m
 var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
 var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
 var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
 Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
 Math.sin(dLon / 2) * Math.sin(dLon / 2);
 var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 var d = R * c;
 return d;
 }
like image 165
manwhowillsoldtheworld Avatar answered Oct 16 '22 17:10

manwhowillsoldtheworld


Was having the same problem. As per this source: http://www.geocodezip.com/v3_GoogleEx_place-search.html I was able to formulate the query as such:

var request = {
location: gps,
types: ['food'], //You can substitute "keyword: 'food'," (without double-quotes) here as well.
rankBy: google.maps.places.RankBy.DISTANCE, //Note there is no quotes here, I made that mistake.
key: key 
};

Var key is API key which is not required but added for later use. GPS is:

var gps = new google.maps.LatLng(location.lat,location.lon);

Lastly, I did everything that you did except I added bounds to a map that I was not going to use. For that I did:

var bounds = new google.maps.LatLngBounds();
like image 20
brutalhonesty Avatar answered Oct 16 '22 15:10

brutalhonesty