Place Autocomplete ウィジェット

欧州経済領域(EEA)のデベロッパー

Place Autocomplete ウィジェットは、テキスト入力フィールドを作成したり、UI の選択リストに場所の候補を表示したり、ユーザーの選択に応えて場所の詳細情報を返したりします。Place Autocomplete ウィジェットを使用すると、完全な自己完結型の予測入力ユーザー インターフェースをウェブページに埋め込むことができます。

前提条件

Place Autocomplete を利用するには、ご使用の Google Cloud プロジェクトで「Places API (new)」を有効化する必要があります。詳しくはスタートガイドをご覧ください。

最新情報

Place Autocomplete は次のように改良されています。

  • Autocomplete ウィジェットのユーザー インターフェースで、テキスト入力のプレースホルダ、予測リストのロゴ、場所の候補が各地域や言語へのローカライズに対応できるようになりました(RTL 言語を含む)。
  • スクリーン リーダーやキーボード操作のサポートなど、ユーザー補助機能が強化されました。
  • Autocomplete ウィジェットが返す新しいプレイスクラスにより、返されたオブジェクトの処理が簡素化されます。
  • モバイル デバイスと小さな画面に対するサポートが強化されました。
  • パフォーマンスとグラフィックの外観が向上しました。

Autocomplete ウィジェットを追加する

Autocomplete ウィジェットは、テキスト入力フィールドを作成し、ユーザー インターフェースの選択リストに候補となる場所を提示します。ユーザーのクリックに対するレスポンスでは、gmp-select リスナーを使用して場所の詳細情報を返します。このセクションでは、Autocomplete ウィジェットをウェブページまたは Google マップに追加する方法について説明します。

Autocomplete ウィジェットをウェブページに追加する

Autocomplete ウィジェットをウェブページに追加するには、新しい 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);

コードサンプルの全文を見る

Autocomplete ウィジェットを地図に追加する

請求先住所が欧州経済領域(EEA)外の場合は、Google マップで Autocomplete ウィジェットを使用することもできます。

Autocomplete ウィジェットを地図に追加するには、新しい google.maps.places.PlaceAutocompleteElement インスタンスを作成し、PlaceAutocompleteElementdiv に追加して、カスタム コントロールとして地図にプッシュします。次のコードサンプルをご覧ください。

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

コードサンプルの全文を見る

予測入力候補を制限する

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Place Details を取得する

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

TypeScript

// Add the gmp-placeselect listener, and display the results.
//@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.
//@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.fetchFields() を呼び出して、アプリケーションに必要な Place Details のデータ フィールドを取得してください。

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

TypeScript

// Add the gmp-placeselect listener, and display the results on the map.
//@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.
//@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 機能付きの要素

以下のサンプルは、Autocomplete ウィジェットをウェブページに追加し、選択された各場所の結果を表示します。

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.
    //@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.
    //@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>

サンプルを試す

Autocomplete 機能付きの地図

以下のサンプルは、Google マップに Autocomplete ウィジェットを追加する方法を示しています。

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.
  //@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.
    //@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>

サンプルを試す

Place Picker コンポーネントを使用する

Place Picker コンポーネントは、エンドユーザーが予測入力機能を使って特定の住所や場所を検索できる、テキスト入力コンポーネントです。これは、より良い地図機能とロケーション機能を迅速に構築できるようにデベロッパーを支援する、一連のウェブ コンポーネントである Extended Component Library に含まれています。

Place Picker 構成ツールを使用すると、Place Picker のカスタム コンポーネントに埋め込み可能なコードを作成して、よく知られているフレームワーク(React や Angular など)にエクスポートして使ったり、フレームワークを一切介さずに使ったりできます。