地点自动补全

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。
选择平台Android iOS JavaScript Web 服务

简介

自动补全是 Maps JavaScript API 中的地点库的一项功能。您可以使用自动补全功能为您的应用提供 Google 地图搜索字段的提前输入搜索行为。自动补全服务可以匹配完整的字词和子字符串,从而解析地点名称、地址和 Plus Code。因此,应用可以在用户输入时发送查询,以提供即时地点预测。

开始使用

在使用 Maps JavaScript API 中的 Places 库之前,请先确保在 Google Cloud Console 中针对您为 Maps JavaScript API 设置的项目中启用了 Places API。

要查看已启用 API 的列表,请执行以下操作:

  1. 转到 Google Cloud Console
  2. 点击选择项目按钮,然后选择您为 Maps JavaScript API 设置的同一项目,然后点击打开
  3. 信息中心的 API 列表中,查找 Places API
  4. 如果您在列表中看到了该 API,就说明一切就绪。如果未列出该 API,请启用:
    1. 在页面顶部,选择 ENABLE API 以显示标签页。或从左侧菜单中选择
    2. 搜索 Places API,然后从结果列表中选择它。
    3. 选择启用。该过程完成后,Places API 会显示在信息中心的 API 列表中。

加载库

Places 服务是一个独立于主 Maps JavaScript API 代码的自包含库。如需使用此库中包含的功能,您必须先在 Maps API 引导加载程序网址中使用 libraries 参数来加载该库:

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
</script>

如需了解详情,请参阅库概览

类摘要

该 API 提供了两种类型的自动补全微件,您可以分别通过 AutocompleteSearchBox 类添加这两种微件。此外,您还可以使用 AutocompleteService 类以编程方式检索自动补全结果(请参阅 Maps JavaScript API 参考文档:AutocompleteService 类)。

以下是可用类的摘要:

  • Autocomplete 会向网页添加文本输入字段,并监控该字段是否含有字符条目。在用户输入文本时,自动补全功能会以下拉选取列表的形式返回地点预测。当用户从列表中选择某个地点后,系统会将该地点的相关信息返回至自动补全对象,并可供您的应用检索。详见下文
    自动填充文本字段,以及用户输入搜索查询时提供的地点预测列表。
    图 1:自动填充文本字段和选择列表
    一份已填写完成的地址表单。
    图 2:完整的地址表单
  • SearchBox 会向您的网页添加文本输入字段,添加方式与 Autocomplete 大致相同。具体区别如下:
    • 主要区别在于选择列表中显示的结果。SearchBox 提供扩展的预测结果列表,其中可能包括地点(如 Places API 所定义)以及建议的搜索字词。例如,如果用户输入“新式披萨”,选择列表可能会包含“北京比较披萨”,以及各种披萨直销店的名称。
    • SearchBox 用于限制搜索的选项少于 Autocomplete。在前者中,您可以使搜索偏向于给定的 LatLngBounds。在后一种情况下,您可以将搜索限制为特定国家/地区和特定地点类型,以及设置边界。如需了解详情,请参阅下文
    一份已填写完成的地址表单。
    图 3:Search Ads 360 显示了搜索字词和地点联想查询。
    详见下文
  • 您可以创建 AutocompleteService 对象来以编程方式检索预测结果。调用 getPlacePredictions() 可检索匹配的地点,或调用 getQueryPredictions() 可检索匹配的地点以及建议的搜索字词。注意:AutocompleteService 不会添加任何界面控件。 但上述方法会返回数组联想查询对象。每个预测对象都包含预测的文本、参考信息和结果与用户输入的匹配方式的详细信息。如需了解详情,请参阅下文

添加自动补全微件

Autocomplete widget 会在网页上创建一个文本输入字段,在界面选择列表中提供地点预测,并返回位置详细信息以响应 getPlace() 请求。选择列表中的每个条目都对应于一个地点(由 Places API 定义)。

Autocomplete 构造函数有两个参数:

  • text 类型的 HTML input 元素。这是自动补全服务将监控并将其结果附加到的输入字段。
  • 可选的 AutocompleteOptions 参数,它可以包含以下属性:
    • 一组数据 fields,将包含在用户所选 PlaceResultPlace Details 响应中。如果未设置该属性或传入 ['ALL'],则返回所有可用字段并结算(不建议用于生产部署)。如需查看字段列表,请参阅 PlaceResult
    • types 数组,用于指定显式类型或类型集合(如支持的类型中所示)。如果未指定类型,则返回所有类型。
    • bounds 是一个 google.maps.LatLngBounds 对象,用于指定搜索地点的区域。结果偏向于(但不限于)这些边界中包含的地点。
    • strictBounds 是一个 boolean,用于指定 API 是否只能返回严格位于给定 bounds 定义的区域内的地点。此 API 不会返回此区域以外的结果,即使结果与用户输入匹配也是如此。
    • componentRestrictions 可用于将结果限制为特定组。目前,您最多可以使用 componentRestrictions 按 5 个国家/地区进行过滤。国家/地区必须以与 ISO 3166-1 Alpha-2 兼容的双字符国家/地区代码的形式进行传递。您必须以国家/地区代码列表的形式传递多个国家/地区。

      注意:如果您收到包含国家/地区代码的意外结果,请确认您使用的代码包含您要定位的国家/地区、附属地区以及特殊地理位置区域。如需了解相关代码信息,请访问 Wikipedia:ISO 3166 国家/地区代码列表ISO 在线浏览平台

    • placeIdOnly 可用于指示 Autocomplete 微件仅检索地点 ID。在对 Autocomplete 对象调用 getPlace() 时,提供的 PlaceResult 将仅设置 place idtypesname 属性。您可以将返回的地点 ID 用于对地点、地理编码、路线或距离矩阵服务的调用。

限制自动补全联想查询

默认情况下,地点自动补全功能会显示所有地点类型,偏向于用户所在位置附近的预测,以及获取用户所选地点的所有可用数据字段。设置地点自动补全选项,以根据您的用例提供更相关的预测结果。

设置施工选项

Autocomplete 构造函数接受 AutocompleteOptions 参数,以便在创建微件时设置约束条件。以下示例设置了 boundscomponentRestrictionstypes 选项以请求 establishment 类型的地点,偏向于指定地理区域中的地点,并且预测范围仅限美国境内的地点。设置 fields 选项可指定返回与用户所选地点相关的信息。

调用 setOptions() 可更改现有微件的选项值。

TypeScript

const center = { lat: 50.064192, lng: -130.605469 };
// Create a bounding box with sides ~10km away from the center point
const defaultBounds = {
  north: center.lat + 0.1,
  south: center.lat - 0.1,
  east: center.lng + 0.1,
  west: center.lng - 0.1,
};
const input = document.getElementById("pac-input") as HTMLInputElement;
const options = {
  bounds: defaultBounds,
  componentRestrictions: { country: "us" },
  fields: ["address_components", "geometry", "icon", "name"],
  strictBounds: false,
  types: ["establishment"],
};

const autocomplete = new google.maps.places.Autocomplete(input, options);

JavaScript

const center = { lat: 50.064192, lng: -130.605469 };
// Create a bounding box with sides ~10km away from the center point
const defaultBounds = {
  north: center.lat + 0.1,
  south: center.lat - 0.1,
  east: center.lng + 0.1,
  west: center.lng - 0.1,
};
const input = document.getElementById("pac-input");
const options = {
  bounds: defaultBounds,
  componentRestrictions: { country: "us" },
  fields: ["address_components", "geometry", "icon", "name"],
  strictBounds: false,
  types: ["establishment"],
};
const autocomplete = new google.maps.places.Autocomplete(input, options);

指定数据字段

指定数据字段,避免为不需要的地点数据 SKU 付费。在传递给 widget 构造函数的 AutocompleteOptions 中添加 fields 属性(如上例所示),或对现有的 Autocomplete 对象调用 setFields()

autocomplete.setFields(["place_id", "geometry", "name"]);

为自动补全功能定义偏差和搜索区域边界

您可以通过以下方式让自动补全结果偏向于某个大致位置或区域:

  • 在创建 Autocomplete 对象时设置边界。
  • 更改现有 Autocomplete 的边界。
  • 将边界设置到地图的视口。
  • 将搜索限制为边界。
  • 将搜索限制在某个特定的国家/地区内。

上面的示例演示了如何在创建时设置边界。以下示例展示了其他自定义调整技术。

更改某个现有 Autocomplete 的边界

调用 setBounds() 以将现有的 Autocomplete 上的搜索区域更改为矩形边界。

TypeScript

const southwest = { lat: 5.6108, lng: 136.589326 };
const northeast = { lat: 61.179287, lng: 2.64325 };
const newBounds = new google.maps.LatLngBounds(southwest, northeast);

autocomplete.setBounds(newBounds);

JavaScript

const southwest = { lat: 5.6108, lng: 136.589326 };
const northeast = { lat: 61.179287, lng: 2.64325 };
const newBounds = new google.maps.LatLngBounds(southwest, northeast);

autocomplete.setBounds(newBounds);
将边界设置到地图的视口。

使用 bindTo() 将结果偏向地图视口,即使该视口发生变化也是如此。

TypeScript

autocomplete.bindTo("bounds", map);

JavaScript

autocomplete.bindTo("bounds", map);

使用 unbind() 将自动补全预测结果与地图视口取消绑定。

TypeScript

autocomplete.unbind("bounds");
autocomplete.setBounds({ east: 180, west: -180, north: 90, south: -90 });

JavaScript

autocomplete.unbind("bounds");
autocomplete.setBounds({ east: 180, west: -180, north: 90, south: -90 });

查看示例

将搜索范围限制为当前范围

设置 strictBounds 选项以将结果限制为当前边界,无论是基于地图视口还是矩形边界。

autocomplete.setOptions({ strictBounds: true });
将预测结果限定在特定国家/地区

使用 componentRestrictions 选项或调用 setComponentRestrictions(),将自动补全搜索功能限定为最多包含一组特定的国家/地区。

TypeScript

autocomplete.setComponentRestrictions({
  country: ["us", "pr", "vi", "gu", "mp"],
});

JavaScript

autocomplete.setComponentRestrictions({
  country: ["us", "pr", "vi", "gu", "mp"],
});

查看示例

限制地点类型

使用 types 选项或调用 setTypes() 将预测限制为特定地点类型。此限制条件指定某个类型或类型集合(如地点类型中所述)。如果未指定约束条件,则会返回所有类型。

对于 types 选项的值或传递给 setTypes() 的值,您可以指定以下任一项:

  • 一个数组,最多可包含表 1表 2 地点类型中的值。例如:

    types: ['hospital', 'pharmacy', 'bakery', 'country']

    或:

    autocomplete.setTypes(['hospital', 'pharmacy', 'bakery', 'country']);
  • 表 3 中的任何项(来自地点类型)。 您只能指定表 3 中的一个值。

如果出现以下情况,该请求将被拒绝:

  • 您指定了超过五种类型。
  • 您指定了任何无法识别的类型。
  • 您可以将表 1表 2 中的任何类型与表 3 中的任何过滤条件混合使用。

地点自动补全演示演示了不同地点类型在预测方面的差异。

访问演示

获取地点信息

当用户从附加到自动填充文本字段的预测结果中选择地点时,该服务会触发 place_changed 事件。如需获取地点详情,请执行以下操作:

  1. place_changed 事件创建事件处理脚本,并对 Autocomplete 对象调用 addListener() 以添加该处理脚本。
  2. Autocomplete 对象调用 Autocomplete.getPlace() 可检索 PlaceResult 对象,您随后可以使用该对象获取有关所选地点的更多信息。

默认情况下,当用户选择某个地点时,自动补全功能会返回所选地点的所有可用数据字段,系统将会向您收取相应的费用。使用 Autocomplete.setFields() 指定要返回的地点数据字段。详细了解 PlaceResult 对象,包括您可以请求的地点数据字段列表。为避免为不需要的数据付费,请务必使用 Autocomplete.setFields() 仅指定您将使用的地点数据。

name 属性包含地点自动补全预测结果中的 description。如需详细了解 description,请参阅地点自动补全文档

对于地址表单,获取结构化格式的地址会很有帮助。要返回所选地点的结构化地址,请调用 Autocomplete.setFields() 并指定 address_components 字段。

以下示例使用自动补全功能填充地址表单中的字段。

TypeScript

function fillInAddress() {
  // Get the place details from the autocomplete object.
  const place = autocomplete.getPlace();
  let address1 = "";
  let postcode = "";

  // Get each component of the address from the place details,
  // and then fill-in the corresponding field on the form.
  // place.address_components are google.maps.GeocoderAddressComponent objects
  // which are documented at http://goo.gle/3l5i5Mr
  for (const component of place.address_components as google.maps.GeocoderAddressComponent[]) {
    // @ts-ignore remove once typings fixed
    const componentType = component.types[0];

    switch (componentType) {
      case "street_number": {
        address1 = `${component.long_name} ${address1}`;
        break;
      }

      case "route": {
        address1 += component.short_name;
        break;
      }

      case "postal_code": {
        postcode = `${component.long_name}${postcode}`;
        break;
      }

      case "postal_code_suffix": {
        postcode = `${postcode}-${component.long_name}`;
        break;
      }

      case "locality":
        (document.querySelector("#locality") as HTMLInputElement).value =
          component.long_name;
        break;

      case "administrative_area_level_1": {
        (document.querySelector("#state") as HTMLInputElement).value =
          component.short_name;
        break;
      }

      case "country":
        (document.querySelector("#country") as HTMLInputElement).value =
          component.long_name;
        break;
    }
  }

  address1Field.value = address1;
  postalField.value = postcode;

  // After filling the form with address components from the Autocomplete
  // prediction, set cursor focus on the second address line to encourage
  // entry of subpremise information such as apartment, unit, or floor number.
  address2Field.focus();
}

JavaScript

function fillInAddress() {
  // Get the place details from the autocomplete object.
  const place = autocomplete.getPlace();
  let address1 = "";
  let postcode = "";

  // Get each component of the address from the place details,
  // and then fill-in the corresponding field on the form.
  // place.address_components are google.maps.GeocoderAddressComponent objects
  // which are documented at http://goo.gle/3l5i5Mr
  for (const component of place.address_components) {
    // @ts-ignore remove once typings fixed
    const componentType = component.types[0];

    switch (componentType) {
      case "street_number": {
        address1 = `${component.long_name} ${address1}`;
        break;
      }

      case "route": {
        address1 += component.short_name;
        break;
      }

      case "postal_code": {
        postcode = `${component.long_name}${postcode}`;
        break;
      }

      case "postal_code_suffix": {
        postcode = `${postcode}-${component.long_name}`;
        break;
      }
      case "locality":
        document.querySelector("#locality").value = component.long_name;
        break;
      case "administrative_area_level_1": {
        document.querySelector("#state").value = component.short_name;
        break;
      }
      case "country":
        document.querySelector("#country").value = component.long_name;
        break;
    }
  }

  address1Field.value = address1;
  postalField.value = postcode;
  // After filling the form with address components from the Autocomplete
  // prediction, set cursor focus on the second address line to encourage
  // entry of subpremise information such as apartment, unit, or floor number.
  address2Field.focus();
}

window.initAutocomplete = initAutocomplete;

查看示例

自定义占位符文本

默认情况下,自动补全服务创建的文本字段包含标准占位符文本。如需修改文本,请在 input 元素上设置 placeholder 属性:

<input id="searchTextField" type="text" size="50" placeholder="Anything you want!">

请注意:默认的占位符文本会自动本地化。如果您指定自己的占位符值,则必须在应用中对该值进行本地化。如需了解 Google Maps JavaScript API 如何选择要使用的语言,请阅读本地化的相关文档。

如需自定义微件的外观,请参阅设置自动补全和搜索框的样式

SearchBox 可让用户执行基于文本的地理搜索,例如“北京烤鸭”或“王府井百货附近的鞋店”。您可以将 SearchBox 附加到文本字段中,用户输入文本后,该服务将以下拉选择列表的形式返回预测结果。

SearchBox 提供扩展的预测结果列表,其中可能包括地点(如 Places API 所定义)以及建议的搜索字词。例如,如果用户输入“新式披萨”,则选取列表可能包含词组“北京烤鸭”,以及各种烤鸭店的名称。当用户从列表中选择某个地点后,该地点的相关信息会返回给 SearchBox 对象,并且您的应用可以检索到该地点。

SearchBox 构造函数有两个参数:

  • text 类型的 HTML input 元素。这是 SearchBox 服务将监控并将其结果附加到的输入字段。
  • options 参数,可以包含 bounds 属性:bounds 是一个 google.maps.LatLngBounds 对象,用于指定要在其中搜索地点的区域。结果偏向于(但不限于)这些边界中包含的地点。

以下代码使用边界参数使结果偏向于通过纬度/经度坐标指定的特定地理区域内的地点。

var defaultBounds = new google.maps.LatLngBounds(
  new google.maps.LatLng(-33.8902, 151.1759),
  new google.maps.LatLng(-33.8474, 151.2631));

var input = document.getElementById('searchTextField');

var searchBox = new google.maps.places.SearchBox(input, {
  bounds: defaultBounds
});

更改搜索框的搜索区域

如需更改现有 SearchBox 的搜索区域,请对 SearchBox 对象调用 setBounds() 并传递相关的 LatLngBounds 对象。

查看示例

获取地点信息

当用户从附加到搜索框的联想查询中选择一项时,该服务会触发 places_changed 事件。您可以对 SearchBox 对象调用 getPlaces(),以检索包含多个预测的数组,每个预测都是一个 PlaceResult 对象。

如需详细了解 PlaceResult 对象,请参阅关于地点详情结果的文档。

TypeScript

// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener("places_changed", () => {
  const places = searchBox.getPlaces();

  if (places.length == 0) {
    return;
  }

  // Clear out the old markers.
  markers.forEach((marker) => {
    marker.setMap(null);
  });
  markers = [];

  // For each place, get the icon, name and location.
  const bounds = new google.maps.LatLngBounds();

  places.forEach((place) => {
    if (!place.geometry || !place.geometry.location) {
      console.log("Returned place contains no geometry");
      return;
    }

    const icon = {
      url: place.icon as string,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(25, 25),
    };

    // Create a marker for each place.
    markers.push(
      new google.maps.Marker({
        map,
        icon,
        title: place.name,
        position: place.geometry.location,
      })
    );

    if (place.geometry.viewport) {
      // Only geocodes have viewport.
      bounds.union(place.geometry.viewport);
    } else {
      bounds.extend(place.geometry.location);
    }
  });
  map.fitBounds(bounds);
});

JavaScript

// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener("places_changed", () => {
  const places = searchBox.getPlaces();

  if (places.length == 0) {
    return;
  }

  // Clear out the old markers.
  markers.forEach((marker) => {
    marker.setMap(null);
  });
  markers = [];

  // For each place, get the icon, name and location.
  const bounds = new google.maps.LatLngBounds();

  places.forEach((place) => {
    if (!place.geometry || !place.geometry.location) {
      console.log("Returned place contains no geometry");
      return;
    }

    const icon = {
      url: place.icon,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(25, 25),
    };

    // Create a marker for each place.
    markers.push(
      new google.maps.Marker({
        map,
        icon,
        title: place.name,
        position: place.geometry.location,
      })
    );
    if (place.geometry.viewport) {
      // Only geocodes have viewport.
      bounds.union(place.geometry.viewport);
    } else {
      bounds.extend(place.geometry.location);
    }
  });
  map.fitBounds(bounds);
});

查看示例

如需自定义微件的外观,请参阅设置自动补全和搜索框的样式

以编程方式检索地点自动补全服务预测

如需以编程方式检索预测结果,请使用 AutocompleteService 类。AutocompleteService 不会添加任何界面控件。相反,它会返回一个预测对象数组,每个对象都包含预测文本、引用信息以及结果如何匹配用户输入的详情。与上述 AutocompleteSearchBox 相比,如果您想更好地控制界面,这会非常有用。

AutocompleteService 提供以下方法:

  • getPlacePredictions() 会返回地点预测。注意:根据 Places API 的定义,“地点”可以是场所、地理位置或著名地图注点,
  • getQueryPredictions() 会返回一个扩展的预测结果列表,其中可能包括地点(如 Places API 所定义)以及建议的搜索字词。例如,如果用户输入“新式披萨”,选择列表可能会包含词组“北京烤鸭”,以及各种烤鸭店的名称。

上述两种方法都会返回以下形式的预测对象数组:

  • description 是匹配的预测。
  • distance_meters 是地点与指定 AutocompletionRequest.origin 之间的距离(以米为单位)。
  • matched_substrings 在说明中包含一组与用户输入中的元素匹配的子字符串。这对于在应用中突出显示这些子字符串很有用。在许多情况下,查询会以说明字段的子字符串的形式显示。
    • length 是子字符串的长度。
    • offset 是从字符字符串开始测量的偏移量(出现在匹配的子字符串处)。
  • place_id 是唯一标识地点的文本标识符。如需检索地点的相关信息,请在地点详情请求placeId 字段中传递此标识符。详细了解如何使用地点 ID 引用地点
  • terms 是包含查询元素的数组。对于地点,每个元素通常构成地址的一部分。
    • offset 是从字符字符串开始测量的偏移量(出现在匹配的子字符串处)。
    • value 是匹配字词。

以下示例针对短语“'披萨附近”执行了查询预测请求,并在列表中显示结果。

TypeScript

// This example retrieves autocomplete predictions programmatically from the
// autocomplete service, and displays them as an HTML list.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initService(): void {
  const displaySuggestions = function (
    predictions: google.maps.places.QueryAutocompletePrediction[] | null,
    status: google.maps.places.PlacesServiceStatus
  ) {
    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") as HTMLUListElement).appendChild(li);
    });
  };

  const service = new google.maps.places.AutocompleteService();

  service.getQueryPredictions({ input: "pizza near Syd" }, displaySuggestions);
}

declare global {
  interface Window {
    initService: () => void;
  }
}
window.initService = initService;

JavaScript

// This example retrieves autocomplete predictions programmatically from the
// autocomplete service, and displays them as an HTML list.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initService() {
  const displaySuggestions = function (predictions, status) {
    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 service = new google.maps.places.AutocompleteService();

  service.getQueryPredictions({ input: "pizza near Syd" }, displaySuggestions);
}

window.initService = initService;

CSS

HTML

<html>
  <head>
    <title>Retrieving Autocomplete Predictions</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <p>Query suggestions for 'pizza near Syd':</p>
    <ul id="results"></ul>
    <!-- Replace Powered By Google image src with self hosted image. https://developers.google.com/maps/documentation/places/web-service/policies#other_attribution_requirements -->
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initService&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

试用示例

查看示例

会话令牌

AutocompleteService.getPlacePredictions() 使用会话令牌对自动补全请求进行分组,以便进行结算。会话令牌将用户自动补全查询的查询和选择阶段归入独立的会话,以便进行结算。会话将在用户开始输入查询时开始,并在用户选择地点时结束。每个会话可以有多个查询,后跟一个地点选择。会话结束后,令牌将失效。您的应用必须为每个会话生成一个新的令牌。我们建议为所有自动补全会话使用会话令牌。如果您省略 sessionToken 参数或重复使用会话令牌,系统会按未提供会话令牌的情况为会话付费(每个请求均单独结算)。

您可以使用同一会话令牌对调用 AutocompleteService.getPlacePredictions() 所产生的地点发出单个地点详情请求。在这种情况下,“自动补全”请求会与“地点详情”请求合并,调用将作为常规“地点详情”请求进行计费。“自动补全”请求是免费的。

请务必为每个新会话传递唯一的会话令牌。对多个“自动补全”会话使用相同的令牌将会让这些“自动补全”会话失效,并且无效会话中的所有“自动补全”请求都将使用按请求结算的 SKU 进行单独收费。详细了解会话令牌

以下示例展示了如何创建会话令牌,然后将其传入 AutocompleteService(为简洁起见,省略了 displaySuggestions() 函数):

// Create a new session token.
var sessionToken = new google.maps.places.AutocompleteSessionToken();

// Pass the token to the autocomplete service.
var autocompleteService = new google.maps.places.AutocompleteService();
autocompleteService.getPlacePredictions({
  input: 'pizza near Syd',
  sessionToken: sessionToken
},
displaySuggestions);

请务必为每个新会话传递唯一的会话令牌。对多个会话使用相同的令牌将导致每个请求单独结算。

详细了解会话令牌

设置自动补全和 SearchBox 微件的样式

默认情况下,AutocompleteSearchBox 提供的界面元素会经过样式设置,以便纳入 Google 地图上。您可能需要根据自己的网站调整样式。您可以使用以下 CSS 类。下面列出的所有类均适用于 AutocompleteSearchBox 微件。

自动补全和 SearchBox 微件的 CSS 类的图示
适用于自动补全和搜索框微件的 CSS 类
CSS 类 说明
pac-container 包含地点自动补全服务返回的预测结果列表的视觉元素。此列表显示为 AutocompleteSearchBox 微件下方的下拉列表。
pac-icon 预测结果列表中每个项目左侧的图标。
pac-item AutocompleteSearchBox 微件提供的预测结果列表中的一项。
pac-item:hover 用户将鼠标指针悬停在其上方的项目。
pac-item-selected 当用户通过键盘选择此类时所显示的项。注意:所选项将是该类和 pac-item 类的成员。
pac-item-query 一个 pac-item 内的跨度,它是预测的主要部分。对于地理位置,它包含地点名称(如悉尼)或街道名称和门牌号码(如 King 街 10 号)。对于基于文本的搜索(例如“北京烤鸭”),则包含查询的完整文本。默认情况下,pac-item-query 显示为黑色。如果 pac-item 中有任何额外文本,该文本不在 pac-item-query 内,并且会继承 pac-item 中的样式。默认情况下,其呈灰色。附加文本通常是地址。
pac-matched 返回的联想查询的一部分,其于用户输入相匹配。默认情况下,此匹配文本以粗体文本突出显示。请注意,匹配的文本可能位于 pac-item 中的任何位置。它不一定是 pac-item-query 的一部分,它可以部分位于 pac-item-query 中,也有一部分位于 pac-item 的剩余文本中。

地点自动补全优化

本部分介绍了帮助您充分利用地点自动补全服务的最佳做法。

以下是一些一般准则:

  • 开发可正常运行的界面的最快方法是使用 Maps JavaScript API 自动补全微件、Places SDK for Android 自动补全微件或 Places SDK for iOS 自动补全界面控件
  • 从一开始就了解重要的地点自动补全数据字段
  • 位置自定义调整和位置限制字段是选填字段,但可能会对自动填充性能产生重大影响。
  • 使用错误处理来确保您的应用在 API 返回错误时妥善降级。
  • 请确保您的应用无需用户选择即可处理,并为用户提供一种继续的方式。

费用优化最佳做法

基本费用优化

为了优化地点自动补全服务的费用,请在“地点详情”和“地点自动补全”微件中使用字段掩码,以便仅返回所需的地点数据字段

高级费用优化

请考虑实现地点自动补全功能,以便访问按请求结算的价格,并请求关于所选地点(而不是地点详情)的 Geocoding API 结果。如果同时满足以下两个条件,则“按请求结算”定价与 Google 会话 API(基于会话)定价相比性价比更高:

  • 如果您只需要用户所选地点的纬度/经度或地址,Google Geocoding API 只需不到地点详情调用一次即可传递此信息。
  • 如果用户选择的自动补全联想查询的平均值在不超过 4 个自动补全预测请求中,则按请求计算的定价可能比按会话结算的性价比更高。
如需我们帮助选择符合您需求的地点自动补全实现,请选择相应问题的答案所对应的标签页。

除了所选联想查询的地址和纬度/经度外,您的应用是否需要其他信息?

是,需要了解更多详情

将基于会话的地点自动补全功能与地点详情搭配使用。
由于您的应用需要地点详情、商家状态或营业时间等地点详情,因此您的地点自动补全实现应使用会话令牌(以编程方式构建,或内置到 JavaScriptAndroidiOS 微件中),总成本为 $0.017每次会话,外加地点数据 SKU,具体取决于您申请的地点数据字段。

微件实现
会话管理会自动内置到
JavaScriptAndroidiOS 微件中。其中包括针对所选联想查询的地点自动补全请求和地点详情请求。请务必指定 fields 参数,以确保您只请求所需的地点数据字段

程序化实现
在地点自动补全请求中使用会话令牌。在请求关于所选预测结果的地点详情时,请添加以下参数:

  1. 来自地点自动补全响应的地点 ID
  2. 地点自动补全请求中使用的会话令牌
  3. fields 参数,用于指定您需要的地点数据字段

不需要,只需要地址和位置

针对您的应用,Geocoding API 可能比地点详情更经济实惠,具体取决于地点自动补全功能的性能。每款应用的自动补全效率都取决于用户输入的内容、用户使用该应用的位置,以及是否实施了性能优化最佳做法

为了回答以下问题,请分析用户在输入地点自动补全联想查询之前平均会输入多少个字符。

您的用户平均能否在不超过 4 个请求内选择地点自动补全联想查询?

在不使用会话令牌的情况下以编程方式实现地点自动补全功能,并对所选地点预测调用 Geocoding API。
Geocoding API 每个请求中的地址地址和纬度/经度坐标均为 0.005 美元。发出四个地点自动补全 - 按请求结算请求的费用为 0.01132 美元,因此加上 4 个请求并针对所选地点预测发出 Geocoding API 调用的总费用将为 0.01632 美元,低于每次会话自动补全价格 ($0.017)。1

您可以考虑采用性能最佳做法,帮助用户以更少的字符找到所需的联想查询。

将基于会话的地点自动补全功能与地点详情搭配使用。
由于您希望在用户选择“地点自动补全”预测之前发出的平均请求次数超出每次会话费用定价,因此,您的“地点自动补全”实现方式应该针对会话自动补全请求和关联的地点详情请求使用会话令牌,总计 $0.017(每次会话)1

微件实现
会话管理会自动内置到 JavaScriptAndroidiOS 微件中。其中包括针对所选联想查询的地点自动补全请求和地点详情请求。请务必指定 fields 参数,以确保您只请求基本数据字段。

程序化实现
在地点自动补全请求中使用会话令牌。在请求关于所选预测结果的地点详情时,请添加以下参数:

  1. 来自地点自动补全响应的地点 ID
  2. 地点自动补全请求中使用的会话令牌
  3. fields 参数,用于指定地址和几何图形等基本数据字段

考虑延迟地点自动补全请求
您可以采取一些策略(例如,推迟用户输入地点自动补全请求,直到用户输入前三个或四个字符),以减少您的应用发出的请求数量。例如,在用户输入第三个字符后,针对每个字符发出地点自动补全请求意味着,如果用户输入 7 个字符,然后您为其发出了一个 Geocoding API 请求,则总费用将为 $0.01632(4 * 每个请求 $0.00283 自动补全 + $0.005 地理编码)。1

如果延迟请求会导致您的平均程序化请求低于 4 次,您可以按照使用 Geocoding API 实现高性能地点自动补全的指南操作。请注意,如果用户希望在每次新的按键操作中看到预测,就会将延迟请求视为延迟时间。

考虑采用性能最佳做法,帮助用户以较少的字符获得他们想要的联想查询。


  1. 此处列出的费用均以美元为单位。如需了解完整的价格信息,请参阅 Google Maps Platform 结算页面。

性能最佳做法

以下指南介绍了优化地点自动补全性能的方法:

  • 向地点自动补全实现添加国家/地区限制、位置自定义调整和语言偏好设置(适用于程序化实现)。微件不需要语言偏好设置,因为它们会从用户的浏览器或移动设备中选择语言偏好设置。
  • 如果地点自动补全功能附有地图,您可以按地图视口调整位置。
  • 如果用户未选择某个自动补全预测结果,通常是因为这些联想查询均不是所需的结果地址,您可以重复使用原始用户输入来尝试获得更相关的结果: 最好回退到使用 Geocoding API 的其他情形包括:
    • 用户在澳大利亚、新西兰或加拿大以外的国家/地区输入分店地址。例如,自动补全功能不支持美国地址“123 Bowdoin St #456, Boston MA, USA”。(自动补全功能仅支持澳大利亚、新西兰和加拿大的分店地址。这三个国家/地区支持的地址格式包括“9/321 Pitt Street, Sydney, New South Wales, Australia”,或“14/19 Langana Avenue, Browns Bay, Auckland, New York”, 或“"145-112 Renfrew Dr, Markham, Antario, Canada”
    • 用户输入地址前缀为“23-30 29 29th 29th St, Queens”的纽约市路段或“47-380 Kamehameha Hwy, Kaneohe”(夏威夷州考爱岛)。

使用限额和政策

配额

如需了解配额和价格,请参阅 Places API 的使用情况和结算文档

政策

使用 Places Library、Maps JavaScript API 时,必须遵守针对 Places API 所述的政策

我们的服务条款要求

显示所需的
徽标和提供方信息

尊重 Google 的版权和出处。确保徽标和版权声明清晰可见,并且如果您在使用地图时不显示数据,则显示“由 Google 提供支持”徽标。

了解详情