基本的な Place Autocomplete の要素

BasicPlaceAutocompleteElement は、テキスト入力フィールドを作成し、UI の選択リストに場所の候補を表示して、選択した場所の場所 ID を返します。

PlaceAutocompleteElement とは対照的に、簡略化された Basic Place Autocomplete 要素では、ユーザーが場所の候補を選択すると入力フィールドがクリアされ、 PlacePrediction オブジェクトではなく、プレイス ID のみを含む プレイス オブジェクトが返されます。このプレイス ID を Places UI キットの詳細要素とともに使用して、場所の詳細情報を取得します。

前提条件

基本的な Place Autocomplete 要素を使用するには、Google Cloud プロジェクトで「Places UI Kit」を有効にする必要があります。詳しくはスタートガイドをご覧ください。

基本的な Place Autocomplete 要素を追加する

Basic Place Autocomplete 要素は、テキスト入力フィールドを作成し、UI の選択リストに場所の候補を表示します。ユーザーの選択に応えて、gmp-select イベントを使用して場所 ID を返します。このセクションでは、基本の Autocomplete 要素をウェブページまたは地図に追加する方法について説明します。

基本的な Autocomplete 要素をウェブページに追加する

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);

予測入力候補を制限する

デフォルトでは、Basic Place Autocomplete はすべてのタイプの場所を表示します。ユーザーの現在地に近い予測を優先します。 BasicPlaceAutocompleteElementOptions を設定すると、表示される結果を制限したり、バイアスを設定したりして、より関連性の高い候補を提示することができます。

制限を適用すると、Basic Autocomplete 要素では指定されたエリア外の結果は無視されます。一般的な制限方法は、結果を地図の境界内のみに限定することです。バイアスを設定すると、指定されたエリア内の結果が優先的に表示されますが、条件によってはエリア外の候補も提示される場合があります。

境界または地図のビューポートを指定しない場合、API は IP アドレスからユーザーの位置を検出し、その位置を優先して結果を返します。境界は可能な限り指定しましょう。指定しなかった場合、表示される候補がユーザーごとに変化する可能性があります。また、一般的に予測精度を高めるためには、地図のパンまたはズームによって設定したような実用的なビューポート、またはデバイスの位置と半径に基づいたデベロッパーによるビューポートを提供することが重要です。半径を指定できない場合は、5 km が Basic Place Autocomplete 要素の有効なデフォルト値とみなされます。半径が 0 のビューポート(単一ポイント)、100 m 未満のビューポート、地球にまたがるビューポートは設定しないでください。

Place Search の結果を特定の国に限定する

Place Search の結果を 1 つ以上の国に限定するには、includedRegionCodes プロパティを使用して国コードを指定します。以下のスニペットをご覧ください。

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

Place Search の結果を地図の境界内に限定する

Place Search の結果を地図の境界内に限定するには、locationRestrictions プロパティを使用して境界を追加します。以下のスニペットをご覧ください。

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

地図の境界内に限定する場合は、リスナーを追加して、境界が変更されたときに境界が更新されるようにしてください。

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

locationRestriction を削除するには、null に設定します。

Place Search の結果にバイアスを設定する

Place Search の結果に円で囲まれた地域を優先的に表示するには、locationBias プロパティを使用して、半径を渡します。コードは以下のようになります。

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

locationBias を削除するには、null に設定します。

Place Search の結果を特定のタイプに限定する

Place Search の結果を特定の場所のタイプに限定するには、includedPrimaryTypes プロパティを使用して、1 つ以上のタイプを指定します。コードは以下のようになります。

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

サポートされているタイプの一覧については、場所のタイプ表 A と B をご覧ください。

Place Details を取得する

選択した場所のプレイス ID を取得するには、gmp-select リスナーを PlaceAutocompleteElement に追加します。以下のコードサンプルをご覧ください。

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

上記のサンプルでは、イベント リスナーはプレイスクラスのオブジェクトを返します。place.fetchFields() を呼び出して、アプリケーションに必要な Place Details のデータ フィールドを取得してください。

次のサンプルのリスナーは、場所の情報をリクエストして、地図上に表示します。

  // Add the gmp-placeselect listener, and display the results on the map.
  //@ts-ignore
  placeAutocomplete.addEventListener('gmp-select', 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;
  });
  

以下のサンプルは、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>

サンプルを試す