通过 GooglePlaces 自动完成的地理搜索:在 X 个字符后开始请求
Geosearch via GooglePlaces Autocomplete: Start requests after X chars
我正在使用以下代码通过 Geosearch 使用 Google Places API:
进行“智能”自动完成
var input = 'field_18';
google.maps.event.addDomListener(document.getElementById(input), 'keydown', function(event) {
if (event.keyCode === 13) {
event.preventDefault();
}
});
var ppx_autocomplete = new google.maps.places.Autocomplete((document.getElementById(input)), { types: ['geocode'] });
ppx_autocomplete.setFields(['geometry', 'formatted_address']);
google.maps.event.addListener(ppx_autocomplete, 'place_changed', function () {
var place = ppx_autocomplete.getPlace();
document.getElementById(input).value = place.formatted_address;
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
document.getElementById('pp_18_geocode').value = latlng;
});
很普通也很直接。
缺点是:自动完成会在输入前 2 或 3 个字母后立即开始,导致对 Google 的大量请求,因此导致我的 API 键消耗。
有什么方法可以限制请求的数量,例如通过仅在 5 个键入的字母之后发送请求并且可能在一些延迟时间之后,例如当用户仍在键入时不发送请求...
您正在查找的内容可以完成,但您需要使用自动完成服务 [1] 而不是自动完成小部件 [2]。下面是一个例子,等到输入第五个字符才发出请求,然后每增加 2 个字符就发出一个。可以在“在此处编辑参数”行编辑字符数。您需要插入自己的 API 密钥。类似的例子在 https://codepen.io/ecglover8/pen/ExPqdNd 每 3 个字符执行一次。
由于您不会使用自动完成小部件,因此您需要自己处理会话令牌 [3](未显示)。从价格的角度来看,您是否需要代币取决于您打算如何使用预测 [4]。此示例实际上使用来自预测的地点 ID 发出地理编码 API 请求并显示 lat/long.
[2] https://developers.google.com/maps/documentation/javascript/places-autocomplete#add-autocomplete
[3] https://developers.google.com/maps/documentation/javascript/places-autocomplete#session_tokens
[4] https://developers.google.com/maps/documentation/places/web-service/usage-and-billing#ac-per-request
//declare constants
const ac = document.getElementById("ac");
const g = document.getElementById("geocoded");
const results = document.getElementById("results");
//listen for typing into input box
ac.addEventListener("input", ACRequest);
//show resulting predictions
const displayPredictions = function(predictions, status) {
results.innerHTML = "";
g.innerHTML = "";
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
predictions.forEach(prediction => {
let li = document.createElement("li");
li.appendChild(document.createTextNode(prediction.description));
li.dataset.placeid = prediction.place_id;
li.addEventListener("click", Geo)
results.appendChild(li);
});
let img = document.createElement("img");
img.setAttribute("src", "https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png");
results.appendChild(img);
};
//make autocomplete request if input value length divisible by 3
function ACRequest() {
//edit params here
if ((ac.value.length > 4) && (ac.value.length % 2 == 1)) {
const service = new google.maps.places.AutocompleteService();
service.getPlacePredictions(
{
//here is where you can add bounds, componentrestrictions, types, etc
input: ac.value
}, displayPredictions
)
};
};
function Geo() {
console.log(this.getAttribute("data-placeid"));
const geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
"placeId": this.getAttribute("data-placeid")
}, function(address, status) {
if (status == "OK") {
g.innerHTML = address[0].geometry.location
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
li {
border: 2px solid blue;
list-style: none;
margin: 2px;
padding: 2px;
}
li:hover {
border: 2px solid red;
}
.pac-card {
border-radius: 2px 0 0 2px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
font-family: Roboto;
margin: 10px 10px 0 0;
outline: none;
}
.title {
background-color: #4D90FE;
color: #FFFFFF;
font-size: 25px;
font-weight: 500;
margin: 10px 0px;
padding: 6px 12px;
}
<div class="pac-card">
<div class="title">Autocomplete Makes Requests Every Three Characters</div>
<input id="ac" size="10" type="text" />
<ul id="results"></ul>
<p id="geocoded"></p>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places&v=weekly" async defer></script>
我正在使用以下代码通过 Geosearch 使用 Google Places API:
进行“智能”自动完成var input = 'field_18';
google.maps.event.addDomListener(document.getElementById(input), 'keydown', function(event) {
if (event.keyCode === 13) {
event.preventDefault();
}
});
var ppx_autocomplete = new google.maps.places.Autocomplete((document.getElementById(input)), { types: ['geocode'] });
ppx_autocomplete.setFields(['geometry', 'formatted_address']);
google.maps.event.addListener(ppx_autocomplete, 'place_changed', function () {
var place = ppx_autocomplete.getPlace();
document.getElementById(input).value = place.formatted_address;
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
document.getElementById('pp_18_geocode').value = latlng;
});
很普通也很直接。
缺点是:自动完成会在输入前 2 或 3 个字母后立即开始,导致对 Google 的大量请求,因此导致我的 API 键消耗。
有什么方法可以限制请求的数量,例如通过仅在 5 个键入的字母之后发送请求并且可能在一些延迟时间之后,例如当用户仍在键入时不发送请求...
您正在查找的内容可以完成,但您需要使用自动完成服务 [1] 而不是自动完成小部件 [2]。下面是一个例子,等到输入第五个字符才发出请求,然后每增加 2 个字符就发出一个。可以在“在此处编辑参数”行编辑字符数。您需要插入自己的 API 密钥。类似的例子在 https://codepen.io/ecglover8/pen/ExPqdNd 每 3 个字符执行一次。
由于您不会使用自动完成小部件,因此您需要自己处理会话令牌 [3](未显示)。从价格的角度来看,您是否需要代币取决于您打算如何使用预测 [4]。此示例实际上使用来自预测的地点 ID 发出地理编码 API 请求并显示 lat/long.
[2] https://developers.google.com/maps/documentation/javascript/places-autocomplete#add-autocomplete
[3] https://developers.google.com/maps/documentation/javascript/places-autocomplete#session_tokens
[4] https://developers.google.com/maps/documentation/places/web-service/usage-and-billing#ac-per-request
//declare constants
const ac = document.getElementById("ac");
const g = document.getElementById("geocoded");
const results = document.getElementById("results");
//listen for typing into input box
ac.addEventListener("input", ACRequest);
//show resulting predictions
const displayPredictions = function(predictions, status) {
results.innerHTML = "";
g.innerHTML = "";
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
predictions.forEach(prediction => {
let li = document.createElement("li");
li.appendChild(document.createTextNode(prediction.description));
li.dataset.placeid = prediction.place_id;
li.addEventListener("click", Geo)
results.appendChild(li);
});
let img = document.createElement("img");
img.setAttribute("src", "https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png");
results.appendChild(img);
};
//make autocomplete request if input value length divisible by 3
function ACRequest() {
//edit params here
if ((ac.value.length > 4) && (ac.value.length % 2 == 1)) {
const service = new google.maps.places.AutocompleteService();
service.getPlacePredictions(
{
//here is where you can add bounds, componentrestrictions, types, etc
input: ac.value
}, displayPredictions
)
};
};
function Geo() {
console.log(this.getAttribute("data-placeid"));
const geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
"placeId": this.getAttribute("data-placeid")
}, function(address, status) {
if (status == "OK") {
g.innerHTML = address[0].geometry.location
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
li {
border: 2px solid blue;
list-style: none;
margin: 2px;
padding: 2px;
}
li:hover {
border: 2px solid red;
}
.pac-card {
border-radius: 2px 0 0 2px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
font-family: Roboto;
margin: 10px 10px 0 0;
outline: none;
}
.title {
background-color: #4D90FE;
color: #FFFFFF;
font-size: 25px;
font-weight: 500;
margin: 10px 0px;
padding: 6px 12px;
}
<div class="pac-card">
<div class="title">Autocomplete Makes Requests Every Three Characters</div>
<input id="ac" size="10" type="text" />
<ul id="results"></ul>
<p id="geocoded"></p>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places&v=weekly" async defer></script>