-1

Так что я слышал, что нет реального чистого способа пакетных запросов referenced here до GooglePlacesAPI; понят.Google Places Api Batch Requests Javascript

Но там должна быть работа.

const retrievePlaces = (google, map, request) => { 
    var places = []; 
    var newPlaces = [] 
    var service = new google.maps.places.PlacesService(map); 

    return new Promise(function(resolve, reject) { 
    service.nearbySearch(request, function(results, status){ 

    if(status == "OK"){ 
     for (var i = 0; i < results.length; i++) { 
      var place = results[i]; 
      places.push(place); 
     } 
     resolve(places); 
     } 
    }); 
    }); 
} 

Я использую вышеуказанную функцию, чтобы сначала получить мои места (это прекрасно работает). Затем я использую:

const retrieveDetails = (google, map, places) => { 

    var gmap = { 
    map: map, 
    google: google 
    }; 

    var placeIds = places.map(function(place){ 
    return { placeId: place.place_id } 
    }); 

    var promiseArray = placeIds.map(place => getPlaceDetailsPromise(place, gmap) 
             .then( res => ({res})) 
             .catch(err => ({err}))); 

    Promise.all(promiseArray) 
    .then(results => { 
     console.log(results); 
    }); 

} 

и:

const getPlaceDetailsPromise = (obj, gmap) => new Promise((resolve, reject) => { 
    var service = new gmap.google.maps.places.PlacesService(gmap.map); 

    service.getDetails(obj, (place, status) => { 
    if (status === google.maps.places.PlacesServiceStatus.OK) { 
     console.log(" Status OK", place); 
     resolve(place); 
    } else { 
     console.log("Not OK"); 
    } 
    }); 
}); 

, чтобы попытаться получить данные для всех мест от PlaceDetailsAPI. Что отстой, так это то, что он действительно работает в определенной степени, но он всегда возвращает только 9 ответов и не более. кроме того, они вышли из строя.

У кого-нибудь есть представление о том, как можно было бы получить детали для каждого места?

ответ

0

Карты клиентских служб API JavaScript API имеют ограничения на сеанс. Об этом говорится в следующем разделе документации:

https://developers.google.com/maps/documentation/javascript/geocoding#UsageLimits

предел частоты, поданного на сессии пользователя, независимо от того, сколько пользователей разделяют один и тот же проект.

Предел скорости сеанса не позволяет использовать клиентские услуги для пакетных запросов, таких как пакетное геокодирование. Для пакетных запросов используйте веб-службу API геокодирования Google Maps.

К сожалению, документация не включает это уведомление в библиотечную часть документации, но она работает одинаково.

Насколько я знаю, изначально у вас есть ведро из 10 запросов. После того, как пустое поле пусто, запрос отклоняется. Ведро заполняется со скоростью 1 запрос в секунду. Таким образом, вы должны активировать свои запросы о деталях мест, чтобы оставаться в пределах разрешенных для сеанса ограничений. В качестве альтернативы вы можете попытаться реализовать запросы пакетных мест на стороне сервера, где у вас будет 50 запросов в секунду (QPS).

0

Спасибо @xomena, и для любого, кто может наткнуться на этот вопрос, есть способ сделать это, и это связано с тем, что упоминалось ранее. Он немного грязный и, вероятно, крайне неэффективен, но делает то, что мне нужно для этого.

Я закончил тем, что сделал небольшое создание ajax/curl, чтобы решить мою проблему и обойти проблемы CORS, которые у меня были. Я сделал прокси-сервер на стороне сервера, который принимает отформатированный запрос google api uri (отправленный через ajax из одной из моих функций) и возвращает объект details.

После этого все работало как шарм. Обновленный код выглядит следующим образом.

const retrievePlaces = (google, map, request) => { 
    var places = [], 
     newPlaces = [], 
     service = new google.maps.places.PlacesService(map); 

    return new Promise(function(resolve, reject) { 
    service.nearbySearch(request, function(results, status){ 
     if(status == "OK"){ 
     for (var i = 0; i < results.length; i++) { 
      var place = results[i]; 
      places.push(place); 
     } 
     resolve(places); 
     } 
    }); 
    }); 
} 

const retrieveDetails = (google, map, places, api) => { 

    var gmap = { map: map, google: google, api_key: api }, 
     placeDetails = [], 
     placeIds = places.map(getPlaceIds), 
     promiseArray = placeIds.map(getPlaceDetails); 

    function getPlaceIds(place){ 
    return { placeId: place.place_id } 
    } 

    function getPlaceDetails(place){ 
    getPlaceDetailsPromise(place, gmap) 
     .then( res => ({res})) 
     .catch(err => ({err})); 
    } 

    return Promise.all(promiseArray); 

} 

const getPlaceDetailsPromise = (obj, gmap) => new Promise((resolve, reject) => { 

    var url = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${obj.placeId}&key=${gmap.api_key}`, 
     qsObj = Qs.parse({ url: url }), 
     qsString = Qs.stringify(qsObj), 
     headerConfig = { 
     headers: { 
      "Content-Type": "application/x-www-form-urlencoded" 
     } 
     }; 

    function resolveDetails(res){ 
    var result = res.data; 
    resolve($.parseJSON(result)); 
    } 

    axios.post('/a/random/path', qsString, headerConfig).then(resolveDetails); 

}); 

И тогда прокси в PHP:

<?php 
/* proxy.php */ 
$url = $_POST["url"]; 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
$result = curl_exec ($ch); 
curl_close ($ch); 

$result = json_encode($result); 

echo $result; 

die(); 
?> 

Конечно, это не будет работать, если вы подключите и играл его в свой код, но идея есть. Если кто-нибудь найдет лучший способ, я бы с удовольствием посмотрел, как вы это сделали, было бы неплохо знать в будущем.