地点自动补全 widget

欧洲经济区 (EEA) 开发者

地点自动补全 widget 会创建一个文本输入字段,在界面选择列表中提供地点预测结果,并返回地点详情以响应用户的选择。使用地点自动补全 widget 在网页上嵌入一个完整的独立自动补全用户界面。

前提条件

若要使用地点自动补全,您必须在 Google Cloud 项目中启用“Places API(新)”。如需了解详情,请参阅开始使用

最新资讯

地点自动补全在以下方面得到了改进:

  • 自动补全 widget 界面针对文本输入占位符、预测列表徽标和地点预测支持区域本地化(包括 RTL 语言)。
  • 增强了无障碍功能,包括对屏幕阅读器和键盘互动的支持。
  • Autocomplete widget 会返回新的 Place 类,以简化对返回对象的处理。
  • 为移动设备和小屏幕设备提供更好的支持。
  • 更出色的性能和改进的图形外观。

添加自动补全 widget

Autocomplete widget 会创建文本输入字段,在界面选择列表中提供地点预测结果,并通过 gmp-select 监听器返回地点详情以响应用户点击。本部分介绍了如何向网页或 Google 地图添加 Autocomplete widget。

向网页添加自动补全 widget

如要向网页添加 Autocomplete widget,请创建一个新的 google.maps.places.PlaceAutocompleteElement,并将其附加到页面,如以下示例所示:

TypeScript

// Request needed libraries.
(await google.maps.importLibrary('places')) as google.maps.PlacesLibrary;
// Create the input HTML element, and append it.
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(
    {}
);
document.body.appendChild(placeAutocomplete);

JavaScript

// Request needed libraries.
(await google.maps.importLibrary('places'));
// Create the input HTML element, and append it.
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement({});
document.body.appendChild(placeAutocomplete);

查看完整代码示例

向地图添加自动补全 widget

如果您的账单邮寄地址位于欧洲经济区 (EEA) 以外,您还可以将自动补全 widget 与 Google 地图搭配使用。

如要向地图添加 Autocomplete widget,请创建一个新的 google.maps.places.PlaceAutocompleteElement 实例,将 PlaceAutocompleteElement 附加到 div,然后将该元素作为自定义控件推送到地图上,如以下示例所示:

TypeScript

// Get the inner map.
innerMap = mapElement.innerMap;
innerMap.setOptions({
    mapTypeControl: false,
});

// Use the bounds_changed event to restrict results to the current map bounds.
google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
    placeAutocomplete.locationRestriction = innerMap.getBounds();
});

JavaScript

// Get the inner map.
innerMap = mapElement.innerMap;
innerMap.setOptions({
    mapTypeControl: false,
});
// Use the bounds_changed event to restrict results to the current map bounds.
google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
    placeAutocomplete.locationRestriction = innerMap.getBounds();
});

查看完整代码示例

限制自动补全预测结果

默认情况下,地点自动补全服务会显示所有地点类型(偏向于用户所在位置附近的预测结果),并提取用户所选地点的所有可用数据字段。 通过限制或自定义调整结果来设置 PlaceAutocompleteElementOptions,可以显示更相关的预测结果。

限制预测结果会导致 Autocomplete widget 忽略限制区域以外的任何结果。常见做法是将结果范围限定在地图边界内。自定义调整结果会使 Autocomplete widget 显示指定区域内的结果,但某些匹配项可能不在这个指定区域内。

如果您未提供任何边界或地图视口,该 API 将尝试根据用户的 IP 地址检测其位置,并使结果偏向于该位置。尽可能设置边界。否则,不同的用户可能会收到不同的预测结果。此外,为了提升总体预测结果准确性,请务必提供合理的视口,例如您通过在地图上平移或缩放来设置的视口,或开发者根据设备位置和半径设置的视口。如果没有半径数据,可将 5 公里视为地点自动补全功能合理的默认选项。请勿设置半径为零(单点)的视口、仅跨几米(100 米以内)的视口,也不要设置横跨全球的视口。

按国家/地区限制地点搜索

如要将地点搜索限定在一个或多个特定国家/地区,请使用 includedRegionCodes 属性指定国家/地区代码,如以下代码段所示:

const pac = new google.maps.places.PlaceAutocompleteElement({
  includedRegionCodes: ['us', 'au'],
});

将地点搜索限定在地图边界内

如要将地点搜索限定在地图的边界内,请使用 locationRestrictions 属性添加边界,如以下代码段所示:

const pac = new google.maps.places.PlaceAutocompleteElement({
  locationRestriction: map.getBounds(),
});

将范围限定在地图边界内时,请务必添加监听器,以在边界发生变化时更新边界:

map.addListener('bounds_changed', () => {
  autocomplete.locationRestriction = map.getBounds();
});

如要移除 locationRestriction,请将其设置为 null

自定义调整地点搜索结果

使用 locationBias 属性并传递半径,即可自定义调整地点搜索结果,将其限定在一个圆形区域内,如下所示:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}},
});

如要移除 locationBias,请将其设置为 null

将地点搜索结果限定为特定类型

使用 includedPrimaryTypes 属性并指定一种或多种类型,即可将地点搜索结果限定为特定类型的地点,如下所示:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  includedPrimaryTypes: ['establishment'],
});

如需查看支持的类型的完整列表,请参阅地点类型表 A 和 B

获取地点详情

如要获取所选地点的地点详情,请向 PlaceAutocompleteElement 添加 gmp-select 监听器,如以下示例所示:

TypeScript

// Add the gmp-placeselect listener, and display the results.
//prettier-ignore
//@ts-ignore
placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
    selectedPlaceTitle.textContent = 'Selected Place:';
    selectedPlaceInfo.textContent = JSON.stringify(
        place.toJSON(), /* replacer */ null, /* space */ 2);
});

JavaScript

// Add the gmp-placeselect listener, and display the results.
//prettier-ignore
//@ts-ignore
placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
    selectedPlaceTitle.textContent = 'Selected Place:';
    selectedPlaceInfo.textContent = JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2);
});

查看完整代码示例

在前面的示例中,事件监听器会返回 Place 类的对象。调用 place.fetchFields() 即可获取应用所需的地点详情数据字段

下例中的监听器会请求地点信息并将其显示在地图上。

TypeScript

// Add the gmp-placeselect listener, and display the results on the map.
  //prettier-ignore
  //@ts-ignore
  placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    await place.fetchFields({
      fields: ['displayName', 'formattedAddress', 'location'],
    });

    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
      innerMap.fitBounds(place.viewport);
    } else {
      innerMap.setCenter(place.location);
      innerMap.setZoom(17);
    }

    let content = document.createElement('div');
    let nameText = document.createElement('span');
    nameText.textContent = place.displayName;
    content.appendChild(nameText);
    content.appendChild(document.createElement('br'));
    let addressText = document.createElement('span');
    addressText.textContent = place.formattedAddress;
    content.appendChild(addressText);

    updateInfoWindow(content, place.location);
    marker.position = place.location;
  }
);

JavaScript

// Add the gmp-placeselect listener, and display the results on the map.
//prettier-ignore
//@ts-ignore
placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
    });
    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
        innerMap.fitBounds(place.viewport);
    }
    else {
        innerMap.setCenter(place.location);
        innerMap.setZoom(17);
    }
    let content = document.createElement('div');
    let nameText = document.createElement('span');
    nameText.textContent = place.displayName;
    content.appendChild(nameText);
    content.appendChild(document.createElement('br'));
    let addressText = document.createElement('span');
    addressText.textContent = place.formattedAddress;
    content.appendChild(addressText);
    updateInfoWindow(content, place.location);
    marker.position = place.location;
});

查看完整代码示例

示例地图

本部分包含本页介绍的示例地图的完整代码。

自动补全元素

此示例会向网页添加 Autocomplete widget,并显示每个选定地点的结果。

TypeScript

async function initMap(): Promise<void> {
    // Request needed libraries.
    (await google.maps.importLibrary('places')) as google.maps.PlacesLibrary;
    // Create the input HTML element, and append it.
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(
        {}
    );
    document.body.appendChild(placeAutocomplete);

    // Inject HTML UI.
    const selectedPlaceTitle = document.createElement('p');
    selectedPlaceTitle.textContent = '';
    document.body.appendChild(selectedPlaceTitle);

    const selectedPlaceInfo = document.createElement('pre');
    selectedPlaceInfo.textContent = '';
    document.body.appendChild(selectedPlaceInfo);

    // Add the gmp-placeselect listener, and display the results.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
        selectedPlaceTitle.textContent = 'Selected Place:';
        selectedPlaceInfo.textContent = JSON.stringify(
            place.toJSON(), /* replacer */ null, /* space */ 2);
    });
}

initMap();

JavaScript

async function initMap() {
    // Request needed libraries.
    (await google.maps.importLibrary('places'));
    // Create the input HTML element, and append it.
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement({});
    document.body.appendChild(placeAutocomplete);
    // Inject HTML UI.
    const selectedPlaceTitle = document.createElement('p');
    selectedPlaceTitle.textContent = '';
    document.body.appendChild(selectedPlaceTitle);
    const selectedPlaceInfo = document.createElement('pre');
    selectedPlaceInfo.textContent = '';
    document.body.appendChild(selectedPlaceInfo);
    // Add the gmp-placeselect listener, and display the results.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
        selectedPlaceTitle.textContent = 'Selected Place:';
        selectedPlaceInfo.textContent = JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2);
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
    height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

p {
    font-family: Roboto, sans-serif;
    font-weight: bold;
}

HTML

<html>
    <head>
        <title>Place Autocomplete element</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
    </head>
    <body>
        <p style="font-family: roboto, sans-serif">Search for a place here:</p>

        <!-- prettier-ignore -->
        <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
    </body>
</html>

试用示例

自动补全地图

以下示例展示了如何向 Google 地图添加 Autocomplete widget。

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
const placeAutocomplete = document.querySelector(
    'gmp-place-autocomplete'
) as google.maps.places.PlaceAutocompleteElement;
let innerMap;
let marker: google.maps.marker.AdvancedMarkerElement;
let infoWindow: google.maps.InfoWindow;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap(): Promise<void> {
    // Request needed libraries.
    const [] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Use the bounds_changed event to restrict results to the current map bounds.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });

    // Create the marker and infowindow.
    marker = new google.maps.marker.AdvancedMarkerElement({
        map: innerMap,
    });

    infoWindow = new google.maps.InfoWindow({});

    // Add the gmp-placeselect listener, and display the results on the map.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
      const place = placePrediction.toPlace();
      await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
      });

      // If the place has a geometry, then present it on a map.
      if (place.viewport) {
        innerMap.fitBounds(place.viewport);
      } else {
        innerMap.setCenter(place.location);
        innerMap.setZoom(17);
      }

      let content = document.createElement('div');
      let nameText = document.createElement('span');
      nameText.textContent = place.displayName;
      content.appendChild(nameText);
      content.appendChild(document.createElement('br'));
      let addressText = document.createElement('span');
      addressText.textContent = place.formattedAddress;
      content.appendChild(addressText);

      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: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}

initMap();

JavaScript

const mapElement = document.querySelector('gmp-map');
const placeAutocomplete = document.querySelector('gmp-place-autocomplete');
let innerMap;
let marker;
let infoWindow;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap() {
    // Request needed libraries.
    const [] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);
    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Use the bounds_changed event to restrict results to the current map bounds.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });
    // Create the marker and infowindow.
    marker = new google.maps.marker.AdvancedMarkerElement({
        map: innerMap,
    });
    infoWindow = new google.maps.InfoWindow({});
    // Add the gmp-placeselect listener, and display the results on the map.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: ['displayName', 'formattedAddress', 'location'],
        });
        // If the place has a geometry, then present it on a map.
        if (place.viewport) {
            innerMap.fitBounds(place.viewport);
        }
        else {
            innerMap.setCenter(place.location);
            innerMap.setZoom(17);
        }
        let content = document.createElement('div');
        let nameText = document.createElement('span');
        nameText.textContent = place.displayName;
        content.appendChild(nameText);
        content.appendChild(document.createElement('br'));
        let addressText = document.createElement('span');
        addressText.textContent = place.formattedAddress;
        content.appendChild(addressText);
        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: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
gmp-map {
    height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

.place-autocomplete-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 5px;
    font-family: Roboto, sans-serif;
    font-size: large;
    font-weight: bold;
}

gmp-place-autocomplete {
    width: 300px;
}

#infowindow-content .title {
    font-weight: bold;
}

#map #infowindow-content {
    display: inline;
}

HTML

<html>
    <head>
        <title>Place Autocomplete map</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
    </head>
    <body>
        <gmp-map center="40.749933,-73.98633" zoom="13" map-id="DEMO_MAP_ID">
            <div
                class="place-autocomplete-card"
                slot="control-inline-start-block-start">
                <p>Search for a place here:</p>
                <gmp-place-autocomplete></gmp-place-autocomplete>
            </div>
        </gmp-map>
    </body>
</html>

试用示例

自动补全(新)优化

本部分介绍了帮助您充分利用自动补全(新)服务的最佳实践。

下面列出了一些一般准则:

  • 若要开发可正常运行的界面,最快的方式是使用 Maps JavaScript API Autocomplete (New) widget、Places SDK for Android Autocomplete (New) widget 或 Places SDK for iOS Autocomplete (New) widget
  • 从一开始就了解重要的自动补全(新)数据字段
  • 位置自定义调整和位置限制字段是可选的,但可能会对自动补全性能产生重大影响。
  • 使用错误处理可确保您的应用在 API 返回错误时妥善降级。
  • 请确保您的应用可以处理没有选择任何内容的情况,并能够让用户继续操作。

费用优化最佳实践

基本费用优化

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

高级费用优化

请考虑通过程序化方式实现自动补全(新),以便采用“自动补全请求”SKU 定价,并请求关于所选地点(而不是地点详情 [新])的 Geocoding API 结果。如果同时满足以下两个条件,与采用“按会话”(基于会话)定价模式相比,将“按请求”定价模式与 Geocoding API 搭配使用的性价比更高:

  • 如果您只需要用户所选地点的纬度/经度或地址,那么采用 Geocoding API 提供此类信息所需的费用会低于调用地点详情(新)所需的费用。
  • 如果用户平均在不超过四次自动补全(新)预测请求之内选择自动补全预测结果,那么“按请求”定价模式可能会比“按会话”定价模式的性价比更高。
如果在选择符合您需求的自动补全(新)实现方面需要帮助,请选择与以下问题的答案相对应的标签页。

除了所选预测结果的地址和纬度/经度外,您的应用是否需要任何其他信息?

是,需要更多详细信息

将基于会话的自动补全(新)与地点详情(新)搭配使用。
由于您的应用需要地点详情(新),例如地点名称、营业状态或营业时间,因此您在实现自动补全(新)时应使用会话令牌(以编程方式或内置于 JavaScriptAndroidiOS widget 中),每个会话一个令牌,并根据您请求的地点数据字段支付适用的 Places SKU 费用。1

widget 实现
会话管理功能自动内置于 JavaScriptAndroidiOS widget 中。这包括针对所选预测结果的“自动补全(新)”请求和“地点详情(新)”请求。请务必指定 fields 参数,以确保您只请求所需的自动补全(新)数据字段

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

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

否,只需要地址和位置信息

对于您的应用,Geocoding API 可能比地点详情(新)性价比更高,具体取决于您使用自动补全(新)的性能。每个应用的自动补全(新)效率各有不同,具体取决于用户输入的内容、使用应用所在的位置,以及是否遵循了性能优化最佳实践

为了回答以下问题,请分析用户在您的应用中选择自动补全(新)预测结果之前平均会输入多少个字符。

平均而言,用户是否能够在不超过四次请求之内选择自动补全(新)预测结果?

在不使用会话令牌的情况下以程序化方式实现自动补全(新),并针对所选的地点预测调用 Geocoding API。
Geocoding API 提供地址和纬度/经度坐标。 发出四次自动补全请求加上针对所选地点预测调用 Geocoding API 的费用低于按会话结算的自动补全(新)费用(按会话结算)。1

您可以考虑采用性能最佳实践,帮助用户以更少的字符找到所需的预测结果。

将基于会话的自动补全(新)与地点详情(新)搭配使用。
由于您预计在用户选择“自动补全(新)”预测结果之前发出的请求的平均数量超过了“按会话”定价的费用,因此您在实现“自动补全(新)”时应为“自动补全(新)”请求和关联的“地点详情(新)”请求使用会话令牌,以便采用按会话定价。 1

widget 实现
会话管理功能自动内置于 JavaScriptAndroidiOS widget 中。这包括针对所选预测结果的“自动补全(新)”请求和“地点详情(新)”请求。请务必指定 fields 参数,以确保您只请求所需的字段。

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

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

考虑延迟“自动补全(新)”请求
您可以采取一些策略,例如延迟“自动补全(新)”请求,直到用户输入前三个或四个字符,从而减少应用发出的请求数量。例如,在用户输入第三个字符,针对每个字符发出自动补全(新)请求,这意味着如果用户输入七个字符,然后选择一个预测结果,而您针对该预测结果发出一个 Geocoding API 请求,则总费用将为 4 次自动补全(新)按请求结算的费用 + Geocoding 费用。1

如果延迟请求会导致平均程序化请求次数低于四次,您可以按照使用 Geocoding API 提高自动补全(新)性能的实现指南操作。请注意,如果用户希望每次输入新的字符后都能看到预测结果,可能会将延迟请求视为时间上的延迟。

您可以考虑采用性能最佳实践,帮助用户以较少的字符找到所需的预测结果。


  1. 如需了解费用,请参阅 Google Maps Platform 价格表

性能最佳实践

下面的指南介绍了优化自动补全(新)性能的方式:

  • 向自动补全(新)实现添加国家/地区限制、位置自定义调整和语言偏好设置(适用于程序化实现)。您无需为 widget 进行语言偏好设置,因为它们会从用户的浏览器或移动设备中选择语言偏好设置。
  • 如果自动补全(新)附有地图,您可以根据地图视口来设置位置偏向。
  • 如果用户未选择任一自动补全(新)预测结果,通常是因为这些预测结果都不是所需的结果地址,您可以重复使用原始用户输入来尝试获取更相关的结果:
    • 如果您希望用户仅输入地址信息,请在调用 Geocoding API 时重复使用原始用户输入。
    • 如果您希望用户按名称或地址查询某个地点,请使用“地点详情(新)”请求。如果希望仅显示特定区域内的结果,请使用位置自定义调整
    适合回退到 Geocoding API 的其他场景包括:
    • 输入子地址的用户,例如建筑物内特定单元或公寓的地址。例如,捷克地址“Stroupežnického 3191/17, Praha”会在自动补全(新)中生成部分预测结果。
    • 用户在输入地址时,需要输入路段前缀,例如纽约的“23-30 29th St, Queens”或夏威夷考爱岛“47-380 Kamehameha Hwy, Kaneohe”。

位置信息偏差

通过传递 location 参数和 radius 参数,使结果偏向指定区域。这会指示自动补全(新)优先显示定义区域内的结果。指定区域以外的结果可能仍会显示。您可以使用 components 参数过滤结果,以仅显示指定国家/地区内的地点。

限制位置

通过传递 locationRestriction 参数,将结果限制在指定区域内。

您还可以添加 locationRestriction 参数,将结果限制为由 locationradius 参数定义的区域。这会指示自动补全(新)返回该区域内的结果。