所以我听说没有真正干净的方法将请求referenced here批量发送到GooglePlacesAPI
;了解。
但必须有一个解决方法。
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 :(得分:1)
Maps JavaScript API客户端服务具有每个会话限制。这在文档的以下部分中提到:
https://developers.google.com/maps/documentation/javascript/geocoding#UsageLimits
每个用户会话应用的速率限制,无论有多少用户共享同一个项目。
每会话速率限制可防止对批处理请求(例如批量地理编码)使用客户端服务。对于批量请求,请使用Google Maps Geocoding API网络服务。
遗憾的是,文档并未在文档的places库部分中包含此通知,但它的工作原理相同。
据我所知,最初你有一堆10个请求。一旦存储桶为空,请求被拒绝。铲斗以每秒1次请求的速度重新填充。因此,您必须限制您的地点详细信息请求,以保持在每个会话限制允许的范围内。或者,您可以尝试在服务器端实现批处理位置请求,您将有50个查询每秒(QPS)限制。
答案 1 :(得分:0)
感谢@xomena,对于任何可能偶然发现这个问题的人来说,有一种方法可以做到这一点,它涉及@xomena之前提到的内容。它有点脏,可能非常低效,但做我需要它做的事情。
我最终做了一个小的ajax / curl开始来解决我的问题并解决我遇到的CORS问题。我创建了一个服务器端代理,它采用格式化的google api请求uri(通过我的一个函数从ajax发送)并返回详细信息对象。
之后,一切都像魅力一样。更新的代码如下。
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();
?>
当然,如果您将其插入代码中并将其播放到代码中,那么这将无效。如果有人找到一种更好的方式,我很乐意看到你是怎么做到的,那将来很有必要知道。