基本地点自动补全元素

请选择平台: Android iOS JavaScript

BasicPlaceAutocompleteElement 会创建一个文本输入字段,在界面选择列表中提供地点预测结果,并返回所选地点的地点 ID。

PlaceAutocompleteElement 相比,简化的基本地点自动补全元素会在用户选择地点预测结果时清除输入字段,并且还会返回一个仅包含地点 ID(而不是 PlacePrediction 对象)的 Place 对象。将此地点 ID 与 Places UI Kit 详情元素搭配使用,可获取更多地点详情。

前提条件

若要使用基本地点自动补全元素,您必须在 Google Cloud 项目中启用“Places 界面套件”。如需了解详情,请参阅开始使用

添加基本地点自动补全元素

基本地点自动补全元素会创建一个文本输入字段,在界面选择列表中提供地点预测结果,并通过 gmp-select 事件返回地点 ID 以响应用户选择。本部分介绍了如何向网页或地图添加基本自动补全元素。

向网页添加基本自动补全元素

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

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

向地图添加基本 Autocomplete 元素

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

  const placeAutocomplete = new google.maps.places.BasicPlaceAutocompleteElement();
  placeAutocomplete.id = 'place-autocomplete-input';
  placeAutocomplete.locationBias = center;
  const card = document.getElementById('place-autocomplete-card');
  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

限制自动补全预测结果

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

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

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

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

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

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

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

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

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

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

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

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

自定义调整地点搜索结果

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

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

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

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

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

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

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

配置地点请求元素

添加一个监听器,以便在用户选择预测结果时更新地点请求元素:

// Add the listener to update the Place Request element when the user selects a prediction
autocompleteElement.addEventListener('gmp-select', async (event) => {
    const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
    placeDetailsRequest.place = event.place.id;
});

以下示例展示了如何向 Google 地图添加基本 Autocomplete 元素。

JavaScript

const mapContainer = document.getElementById("map-container");
const autocompleteElement = document.querySelector('gmp-basic-place-autocomplete');
const detailsElement = document.querySelector('gmp-place-details-compact');
const mapElement = document.querySelector('gmp-map');
const advancedMarkerElement = document.querySelector('gmp-advanced-marker');
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap() {
    //@ts-ignore
    const { BasicPlaceAutocompleteElement, PlaceDetailsElement } = await google.maps.importLibrary('places');
    //@ts-ignore
    const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');
    //@ts-ignore
    const { LatLngBounds } = await google.maps.importLibrary('core');
    // Set the initial map location and autocomplete location bias
    mapElement.center = center;
    autocompleteElement.locationBias = center;
    // Get the underlying google.maps.Map object to add listeners
    const map = mapElement.innerMap;
    // Add the listener tochange locationBias to locationRestriction when the map moves
    map.addListener('bounds_changed', () => {
        autocompleteElement.locationBias = null;
        autocompleteElement.locationRestriction = map.getBounds();
        console.log("bias changed to restriction");
    });
    // Add the listener to update the Place Request element when the user selects a prediction
    autocompleteElement.addEventListener('gmp-select', async (event) => {
        const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
        placeDetailsRequest.place = event.place.id;
    });
    // Add the listener to update the marker when the Details element loads
    detailsElement.addEventListener('gmp-load', async () => {
        const location = detailsElement.place.location;
        detailsElement.style.display = "block";
        advancedMarkerElement.position = location;
        advancedMarkerElement.content = detailsElement;
        if (detailsElement.place.viewport) {
            map.fitBounds(detailsElement.place.viewport);
        }
        else {
            map.setCenter(location);
            map.setZoom(17);
        }
    });
}
initMap();

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map-container {
  display: flex;
  flex-direction: row;
  height: 100%;
}

#gmp-map {
  height: 100%;
}

gmp-basic-place-autocomplete {
  position: absolute;
  height: 50px;
  top: 10px;
  left: 10px;
  z-index: 1;
  box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); 
  color-scheme: light;
  border-radius: 10px;
}

gmp-place-details-compact {
  width: 360px;
  max-height: 300px;
  border: none;
  padding: 0;
  margin: 0;
  position: absolute;
  transform: translate(calc(-180px), calc(-215px)); 
  box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); 
  color-scheme: light;
}

/* This creates the pointer attached to the bottom of the element. */
gmp-place-details-compact::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 16px solid transparent;
  border-right: 16px solid transparent;
  border-top: 20px solid var(--gmp-mat-color-surface, light-dark(white, black));
}

HTML

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

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
   <div id="map-container">
      <gmp-basic-place-autocomplete></gmp-basic-place-autocomplete>
      <gmp-place-details-compact orientation="horizontal">
        <gmp-place-details-place-request></gmp-place-details-place-request>
        <gmp-place-all-content></gmp-place-all-content>
      </gmp-place-details-compact>
      <gmp-map zoom="14" map-id="DEMO_MAP_ID">
         <gmp-advanced-marker></gmp-advanced-marker> 
      </gmp-map>
    </div>

    <!-- 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>

试用示例