谷歌地图API V3如何按最近距离排序

8

有人知道如何使用此处提到的按距离排名搜索选项吗? https://developers.google.com/maps/documentation/javascript/places#place_search_requests

将其列在请求选项中似乎没有起作用。以下是我相对于此的代码部分:

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]);
        }
    } 
}

如果我包括半径,代码将定位并列出结果,但结果不按距离升序列出。谷歌文档说,如果使用rankBy选项,则不需要半径。我有什么遗漏吗?


我也在同样的情况下...正在寻找解决方案。 - GuiDoody
4个回答

13

您不能同时使用半径和RankBy.DISTANCE属性。因此,您有两个选项:

1)在自己的代码中通过半径搜索,然后按距离排序结果。

示例:

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]);
       }
   } 
}

选项2:按RankBy.Distance搜索,然后使用半径限制结果。同样,您需要使用haversine公式来计算距离。

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;
 }

这对我来说绝对是正确的答案,我遇到了与@JFlo相同的问题。 - David

9

我也遇到了同样的问题。 根据这个来源:http://www.geocodezip.com/v3_GoogleEx_place-search.html 我能够构建如下查询:

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是API密钥,目前不是必需的,但为以后的使用添加了。GPS是:

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

最后,我做了除了在一个我不打算使用的地图上增加范围之外的一切。为此,我这样做了:
var bounds = new google.maps.LatLngBounds();

如果你想用变量替换值,那么'types'应该改为'type'。否则,它将无法正常工作。 - rmutalik

4

您不能同时使用半径和rankBy属性。

如果您需要最接近的位置,请选择一些类型,并设置rankBy属性。

places.nearbySearch({
                        location: LatLng,
                        types: placeTypes,
                        rankBy: google.maps.places.RankBy.DISTANCE
                    },
                    function (results) {
                        // process the results, r[0] is the closest place
                    }
                );

您可以在此处设置placeTypes,例如:

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'

];


1
请注意,在当前的Api文档中,PlacesService类的“search”方法不可用

https://developers.google.com/maps/documentation/javascript/reference?hl=it#PlacesService

你需要在以下选项中进行选择:

  • nearbySearch(每页检索20个结果,最多3页)
  • radarSearch(检索200个结果,但详细程度较低)
  • textSearch(与nearbySearch类似)

如果您选择RankBy.DISTANCE,则无法设置半径

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();
  } 
});

如果您想基于距离半径限制数据,则可以使用此函数检查结果是否太远。
function checkRadiusDistance(place,centerLatLng,radius) {
  return google.maps.geometry.spherical.computeDistanceBetween(place.geometry.location, centerLatLng) < radius;
});

请注意,这也是唯一的方法来获取某个半径内的位置,因为当您指定“rankBy:google.maps.places.RankBy.PROMINENCE”和“radius=xx”时,placesService会给您提供定义区域之外的结果。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接