问题
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?
回答1:
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();
回答2:
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;
}
回答3:
You cannot use radius + rankBy properties together.
If you need the closest locations, choose some types, and set the rankBy proprety.
places.nearbySearch({
location: LatLng,
types: placeTypes,
rankBy: google.maps.places.RankBy.DISTANCE
},
function (results) {
// process the results, r[0] is the closest place
}
);
where you can set placeTypes like this
var placeTypes = [
'accounting',
'airport',
'amusement_park',
'aquarium',
'art_gallery',
'atm',
'bakery',
'bank',
'bar',
'beauty_salon',
'bicycle_store',
'book_store',
'bowling_alley',
'bus_station',
'cafe',
'campground',
'car_dealer',
'car_rental',
'car_repair',
'car_wash',
'casino',
'cemetery',
'church',
'city_hall',
'clothing_store',
'convenience_store',
'courthouse',
'dentist',
'department_store',
'doctor',
'electrician',
'electronics_store',
'embassy',
'establishment',
'finance',
'fire_station',
'florist',
'food',
'funeral_home',
'furniture_store',
'gas_station',
'general_contractor',
'grocery_or_supermarket',
'gym',
'hair_care',
'hardware_store',
'health',
'hindu_temple',
'home_goods_store',
'hospital',
'insurance_agency',
'jewelry_store',
'laundry',
'lawyer',
'library',
'liquor_store',
'local_government_office',
'locksmith',
'lodging',
'meal_delivery',
'meal_takeaway',
'mosque',
'movie_rental',
'movie_theater',
'moving_company',
'museum',
'night_club',
'painter',
'park',
'parking',
'pet_store',
'pharmacy',
'physiotherapist',
'place_of_worship',
'plumber',
'police',
'post_office',
'real_estate_agency',
'restaurant',
'roofing_contractor',
'rv_park',
'school',
'shoe_store',
'shopping_mall',
'spa',
'stadium',
'storage',
'store',
'subway_station',
'synagogue',
'taxi_stand',
'train_station',
'travel_agency',
'university',
'veterinary_care',
'zoo'
];
回答4:
Please note that on the current Api Doc the "search" method on the PlacesService class is not available.
https://developers.google.com/maps/documentation/javascript/reference?hl=it#PlacesService
You have to choose betwen:
- nearbySearch (retrieve 20 result per page, max 3 pages)
- radarSearch (retrieve 200 result but with less details)
- textSearch (similar to the nearbySearch)
If you choose to RankBy.DISTANCE you cant set the radius
var request = {
location: vLatLng,
//radius: vRaggio,
rankBy: google.maps.places.RankBy.DISTANCE,
keyword: ['puma, retail'],
types: ['store']
}
placesService.nearbySearch(request, function (data, status, placeSearchPagination) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
//...
// do your stuffs with data results
//...
if (placeSearchPagination && placeSearchPagination.hasNextPage) {
placeSearchPagination.nextPage();
}
});
If you want to restrict data based on a distance radius you can use this function to check if the resut is too far.
function checkRadiusDistance(place,centerLatLng,radius) {
return google.maps.geometry.spherical.computeDistanceBetween(place.geometry.location, centerLatLng) < radius;
});
Please note that this is also the only way to obtain places inside a certain radius beacuse when you specify "rankBy:google.maps.places.RankBy.PROMINENCE" and a "radius=xx" the placesService give you also results outside the defined area.
来源:https://stackoverflow.com/questions/10726533/google-maps-api-v3-how-to-rank-by-closest-distance