地点自动补全是 Maps JavaScript API 中地点库的一项功能。您可以使用自动补全功能让您的应用具有 Google 地图搜索字段的提前键入搜索行为。
本页介绍了旧版和新版地点自动补全功能之间的差异。在这两个版本中,集成自动补全功能有两种常规方法:
- 程序化接口:适用于希望对自动补全体验进行更大自定义和控制的开发者。
- 地点自动补全 widget:可嵌入到地图或网页中的搜索栏。
自动补全程序化接口
下表列出了在使用程序化地点自动补全功能时,地点自动补全服务(旧版)和 Autocomplete Data API(新版)之间的一些主要区别:
PlacesService (旧版) |
Place (新) |
---|---|
地点自动补全服务参考文档 | 自动补全数据(新)参考文档 |
AutocompletionRequest |
AutocompleteRequest |
AutocompleteService.getPlacePredictions |
AutocompleteSuggestion.fetchAutocompleteSuggestions |
AutocompletePrediction |
PlacePrediction |
方法需要使用回调来处理结果对象和 PlacesServiceStatus 响应。 |
使用 Promise,并以异步方式运行。 |
方法需要进行 PlacesServiceStatus 检查。 |
无需状态检查,可以使用标准错误处理。 |
创建 Autocomplete 实例时,地点数据字段会设置为选项。 |
地点数据字段会在稍后调用 fetchFields() 时设置。 |
支持查询预测(仅限 SearchBox )。 |
Autocomplete 类不提供查询预测。 |
仅限于一组固定的地点类型和地点数据字段。 | 使用更多地点类型和地点数据字段。 |
旧版和新版 Autocomplete API 都使用以下内容:
代码比较(程序化)
本部分比较了自动补全的代码,以说明程序化接口的 Places 服务和 Place 类之间的区别。
检索自动补全联想查询(旧版)
借助旧版地点服务,您可以通过编程方式检索自动补全预测结果,从而比 Autocomplete
类提供的更强大的用户界面控制功能。在以下示例中,系统会针对“par”发出单个请求,其中 AutocompletionRequest
由输入值和一组用于偏向预测的边界组成。该示例会返回 AutocompletePrediction
实例的列表,并显示每个实例的说明。示例函数还会创建一个会话令牌并将其应用于请求。
function init() {
const placeInfo = document.getElementById("prediction");
const service = new google.maps.places.AutocompleteService();
const placesService = new google.maps.places.PlacesService(placeInfo);
var sessionToken = new google.maps.places.AutocompleteSessionToken();
// Define request options.
let request = {
input: "par",
sessionToken: sessionToken,
bounds: {
west: -122.44,
north: 37.8,
east: -122.39,
south: 37.78,
},
}
// Display the query string.
const title = document.getElementById("title");
title.appendChild(
document.createTextNode('Place predictions for "' + request.input + '":'),
);
// Perform the query and display the results.
const displaySuggestions = function (predictions, status) {
// Check the status of the Places Service.
if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
alert(status);
return;
}
predictions.forEach((prediction) => {
const li = document.createElement("li");
li.appendChild(document.createTextNode(prediction.description));
document.getElementById("results").appendChild(li);
});
const placeRequest = {
placeId: predictions[0].place_id,
fields: ["name", "formatted_address"],
};
placesService.getDetails(placeRequest, (place, status) => {
if (status == google.maps.places.PlacesServiceStatus.OK && place) {
placeInfo.textContent = `
First predicted place: ${place.name} at ${place.formatted_address}`
}
});
};
// Show the results of the query.
service.getPlacePredictions(request, displaySuggestions);
}
检索自动补全联想查询(新)
借助新的地点类,您还可以通过编程方式检索自动补全预测结果,从而比 PlaceAutocompleteElement
类提供的更强大的用户界面控制功能。在以下示例中,系统会针对“par”发出单个请求,其中 AutocompleteRequest
由输入值和一组用于偏向预测的边界组成。该示例会返回 placePrediction
实例的列表,并显示每个实例的说明。示例函数还会创建一个会话令牌并将其应用于请求。
async function init() {
let sessionToken = new google.maps.places.AutocompleteSessionToken();
// Define request options.
let request = {
input: "par",
sessionToken: sessionToken,
locationBias: {
west: -122.44,
north: 37.8,
east: -122.39,
south: 37.78,
},
};
// Display the query string.
const title = document.getElementById("title");
title.appendChild(
document.createTextNode('Place predictions for "' + request.input + '":'),
);
// Perform the query and display the results.
const { suggestions } =
await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
const resultsElement = document.getElementById("results");
for (let suggestion of suggestions) {
const placePrediction = suggestion.placePrediction;
const listItem = document.createElement("li");
listItem.appendChild(
document.createTextNode(placePrediction.text.text),
);
resultsElement.appendChild(listItem);
}
// Show the first predicted place.
let place = suggestions[0].placePrediction.toPlace();
await place.fetchFields({
fields: ["displayName", "formattedAddress"],
});
const placeInfo = document.getElementById("prediction");
placeInfo.textContent = `
First predicted place: ${place.displayName} at ${place.formattedAddress}`
}
- 地点自动补全数据 API
- 地点自动补全数据预测示例
- 地点自动补全数据会话示例
- 会话令牌
AutocompleteRequest
接口参考文档AutocompleteSuggestion
类引用PlacePrediction
类引用
地点自动补全 widget
下表列出了使用地点服务(旧版)和地点类(新版)自动补全 widget 的一些主要区别:
地点服务(旧版) | 地点(新) |
---|---|
用于地点预测的 Autocomplete 类。
|
用于地点预测的 PlaceAutocompleteElement 类。
|
用于查询预测的 SearchBox 类。 |
Autocomplete 类不提供查询预测。
|
只有默认的输入占位符文本会本地化。 | 文本输入占位符、预测列表徽标和地点预测均支持区域本地化。 |
Widget 使用
setBounds() 或 autocomplete.bindTo() 将搜索范围限制(偏向)到指定边界,并使用
strictBounds 将结果限制到指定边界。
|
微件使用 locationBias 属性自定义调整结果,将其限定在指定边界内,并使用 locationRestriction 属性将搜索范围限制在指定边界内。
|
只能使用标准 HTML 输入元素集成 widget。 | 您可以使用标准 HTML 输入元素或 gmp-place-autocomplete 元素集成微件。 |
使用该 widget 时,用户可能会请求可能无效的内容(例如“bisneyland”);必须明确处理这种情况。 | 该 widget 只会针对所提供的建议返回结果,无法针对任意值发出请求;因此,无需处理可能无效的请求。 |
返回旧版
PlaceResult 实例。 |
返回
Place 实例。 |
地点数据字段被设置为 Autocomplete 对象的选项。 |
当用户进行选择并调用 fetchFields() 时,系统会设置地点数据字段。 |
仅限于一组固定的地点类型和地点数据字段。 | 使用更多地点类型和地点数据字段。 |
代码比较(微件)
本部分比较了自动补全功能的代码,以说明旧版地点自动补全微件与新版地点自动补全元素之间的区别。
地点自动补全 widget(旧版)
地点服务提供了两种类型的自动补全 widget,您可以使用 Autocomplete
和 SearchBox
类添加它们。每种类型的 widget 都可以作为地图控件添加到地图中,也可以直接嵌入到网页中。以下代码示例展示了如何将 Autocomplete
微件作为地图控件嵌入。
Autocomplete
widget 构造函数有两个参数:- 一个是
text
类型的 HTMLinput
元素。这是自动补全服务将监控并将其结果附于其中的输入字段。 - 一个可选的
AutocompleteOptions
参数,您可以在其中指定用于约束查询的其他选项。
- 一个是
- 如需设置边界,可以通过调用
autocomplete.bindTo()
将Autocomplete
实例显式绑定到地图。 - 在自动补全选项中指定地点数据字段。
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 40.749933, lng: -73.98633 },
zoom: 13,
mapTypeControl: false,
});
const card = document.getElementById("pac-card");
const input = document.getElementById("pac-input");
const options = {
fields: ["formatted_address", "geometry", "name"],
strictBounds: false,
};
map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
const autocomplete = new google.maps.places.Autocomplete(input, options);
// Bind the map's bounds (viewport) property to the autocomplete object,
// so that the autocomplete requests use the current map bounds for the
// bounds option in the request.
autocomplete.bindTo("bounds", map);
const infowindow = new google.maps.InfoWindow();
const infowindowContent = document.getElementById("infowindow-content");
infowindow.setContent(infowindowContent);
const marker = new google.maps.Marker({
map,
anchorPoint: new google.maps.Point(0, -29),
});
autocomplete.addListener("place_changed", () => {
infowindow.close();
marker.setVisible(false);
const place = autocomplete.getPlace();
if (!place.geometry || !place.geometry.location) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
window.alert("No details available for input: '" + place.name + "'");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
infowindowContent.children["place-name"].textContent = place.name;
infowindowContent.children["place-address"].textContent =
place.formatted_address;
infowindow.open(map, marker);
});
}
地点自动补全 widget(新)
Place 类提供了 PlaceAutocompleteElement
,这是一个 HTMLElement
子类,提供的界面组件可作为地图控件添加到地图中,或直接嵌入到网页中。以下代码示例展示了如何将 PlaceAutocompleteElement
微件嵌入为地图控件。
地点自动补全微件在以下方面得到了改进:
- Autocomplete widget 界面针对文本输入占位符、预测列表徽标和地点预测支持区域本地化(包括 RTL 语言)。
- 增强了无障碍功能,包括对屏幕阅读器和键盘互动的支持。
- Autocomplete widget 会返回新的
Place
类,以简化对返回对象的处理。 - 为移动设备和小屏幕设备提供更好的支持。
- 更出色的性能和改进的图形外观。
主要实现差异包括:
Autocomplete
类不支持查询预测。PlaceAutocompleteElement
是使用PlaceAutocompleteElementOptions
构造的。- 地点数据字段是在选择时(调用
fetchFields()
时)指定的。 - 使用
locationBounds
或locationRestriction
选项设置边界。 - 使用
id
属性(从HTMLElement
继承)将PlaceAutocompleteElement
与 HTML 文本输入元素相关联。
let map;
let marker;
let infoWindow;
async function initMap() {
// Request needed libraries.
const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
google.maps.importLibrary("marker"),
google.maps.importLibrary("places"),
]);
// Initialize the map.
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 40.749933, lng: -73.98633 },
zoom: 13,
mapId: "4504f8b37365c3d0",
mapTypeControl: false,
});
const placeAutocomplete =
new google.maps.places.PlaceAutocompleteElement({
locationRestriction: map.getBounds(),
});
placeAutocomplete.id = "place-autocomplete-input";
const card = document.getElementById("place-autocomplete-card");
card.appendChild(placeAutocomplete);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
// Create the marker and infowindow.
marker = new google.maps.marker.AdvancedMarkerElement({
map,
});
infoWindow = new google.maps.InfoWindow({});
// Add the gmp-placeselect listener, and display the results on the map.
placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
await place.fetchFields({
fields: ["displayName", "formattedAddress", "location"],
});
// If the place has a geometry, then present it on a map.
if (place.viewport) {
map.fitBounds(place.viewport);
} else {
map.setCenter(place.location);
map.setZoom(17);
}
let content =
'<div id="infowindow-content">' +
'<span id="place-displayname" class="title">' +
place.displayName +
'</span><br />' +
'<span id="place-address">' +
place.formattedAddress +
'</span>' +
'</div>';
updateInfoWindow(content, place.location);
marker.position = place.location;
});
}
// Helper function to create an info window.
function updateInfoWindow(content, center) {
infoWindow.setContent(content);
infoWindow.setPosition(center);
infoWindow.open({
map,
anchor: marker,
shouldFocus: false,
});
}