新しい Place Autocomplete に移行する

Place Autocomplete は、Maps JavaScript API のプレイス ライブラリの機能です。オートコンプリートを使用すると、Google マップの検索フィールドの予測入力検索動作をアプリケーションに組み込むことができます。

このページでは、従来の Places Autocomplete 機能と新しい Places Autocomplete 機能の違いについて説明します。どちらのバージョンでも、自動入力を統合する方法は一般的に 2 つあります。

自動入力プログラマティック インターフェース

次の表に、Places Autocomplete Service(従来版)Autocomplete Data API(新規)におけるプログラムによる Place Autocomplete の使用方法の主な違いを示します。

PlacesService(レガシー) Place(新規)
Place Autocomplete サービスのリファレンス Autocomplete Data(新規)リファレンス
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
メソッドでは、結果オブジェクトと PlacesServiceStatus レスポンスを処理するためにコールバックを使用する必要があります。 Promise を使用し、非同期で動作します。
メソッドには PlacesServiceStatus チェックが必要です。 ステータス チェックは不要で、標準のエラー処理を使用できます。
プレースデータ フィールドは、Autocomplete インスタンスの作成時にオプションとして設定されます。 プレイスデータ フィールドは、fetchFields() が呼び出された後に設定されます。
クエリ予測がサポートされています(SearchBox のみ)。 Autocomplete クラスではクエリ予測を使用できません。
場所タイプ場所データ項目の固定セットに制限されます。 場所の種類場所データ項目の選択肢が拡大されました。

従来の Autocomplete API と新しい Autocomplete API の両方で使用される項目は次のとおりです。

コードの比較(プログラムによる)

このセクションでは、プログラムによるインターフェースのオートコンプリートのコードを比較して、Places サービスと Place クラスの違いを示します。

予測入力候補を取得する(従来版)

従来の Places サービスを使用すると、自動入力の予測をプログラムで取得できるため、Autocomplete クラスよりもユーザー インターフェースを細かく制御できます。次の例では、「par」に対して 1 つのリクエストが送信され、入力値と予測のバイアスのための一連の境界で構成される AutocompletionRequest が使用されます。この例では、AutocompletePrediction インスタンスのリストを返して、各インスタンスの説明を表示します。サンプル関数は、セッション トークンを作成してリクエストに適用します。

function init() {
  const placeInfo = document.getElementById("prediction");
  const service = new google.maps.places.AutocompleteService();
  const placesService = new google.maps.places.PlacesService(placeInfo);
  var sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    bounds: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  }

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const displaySuggestions = function (predictions, status) {
    // Check the status of the Places Service.
    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 placeRequest = {
      placeId: predictions[0].place_id,
      fields: ["name", "formatted_address"],
    };

    placesService.getDetails(placeRequest, (place, status) => {
      if (status == google.maps.places.PlacesServiceStatus.OK && place) {
        placeInfo.textContent = `
          First predicted place: ${place.name} at ${place.formatted_address}`
      }
    });

  };

  // Show the results of the query.
  service.getPlacePredictions(request, displaySuggestions);
}

予測入力候補を取得する(新規)

新しい Place クラスを使用すると、オートコンプリートの候補をプログラマティックに取得して、PlaceAutocompleteElement クラスよりもユーザー インターフェースを細かく制御できます。次の例では、「par」に対して 1 つのリクエストが送信され、AutocompleteRequest は入力値と予測のバイアスのための一連の境界で構成されています。この例では、placePrediction インスタンスのリストを返して、各インスタンスの説明を表示します。サンプル関数は、セッション トークンを作成してリクエストに適用します。

async function init() {
  let sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    locationBias: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  };

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

  const resultsElement = document.getElementById("results");

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    const listItem = document.createElement("li");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.text),
    );

    resultsElement.appendChild(listItem);
  }

  // Show the first predicted place.
  let place = suggestions[0].placePrediction.toPlace();

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent = `
    First predicted place: ${place.displayName} at ${place.formattedAddress}`
}

プレイス オートコンプリート ウィジェット

次の表に、Places サービス(従来版)と Place クラス(新規)の自動入力ウィジェットの使用における主な違いを示します。

プレイス サービス(従来版) プレイス(新規)
場所の予測用の Autocomplete クラス。 場所の予測用の PlaceAutocompleteElement クラス。
クエリ予測用の SearchBox クラス
Autocomplete クラスではクエリ予測を使用できません。
ローカライズされるのは、デフォルトの入力プレースホルダ テキストのみです。 テキスト入力のプレースホルダ、予測リストのロゴ、場所の候補は、地域ごとのローカライズに対応しています。
ウィジェットは、 setBounds() または autocomplete.bindTo() を使用して検索を指定された範囲に制限(バイアス)し、 strictBounds を使用して結果を指定された範囲に制限します。 ウィジェットは、locationBias プロパティを使用して結果に指定した境界を優先し、locationRestriction プロパティを使用して検索を指定された境界に制限します。
ウィジェットを統合できるのは、標準の HTML 入力要素を使用する場合のみです。 ウィジェットは、標準の HTML 入力要素または gmp-place-autocomplete 要素を使用して統合できます。
ウィジェットを使用すると、ユーザーが有効でないものをリクエストする可能性があります(「bisneyland」など)。この場合は、明示的に処理する必要があります。 ウィジェットは、指定された候補の結果のみを返します。任意の値のリクエストを発行することはできないため、無効なリクエストを処理する必要はありません。
以前の PlaceResult インスタンスを返します。 Place インスタンスを返します。
プレースデータ フィールドは、Autocomplete オブジェクトのオプションとして設定されます。 場所データ フィールドは、ユーザーが選択して fetchFields() が呼び出されると設定されます。
場所タイプ場所データ項目の固定セットに制限されます。 場所の種類場所データ項目の選択肢が拡大されました。

コードの比較(ウィジェット)

このセクションでは、オートコンプリートのコードを比較して、従来の Place Autocomplete ウィジェットと新しい Place Autocomplete 要素の違いを示します。

Place Autocomplete ウィジェット(従来版)

Places サービスには、2 種類のオートコンプリート ウィジェットが用意されており、Autocomplete クラスと SearchBox クラスを使用して追加できます。各種類のウィジェットは、地図コントロールとして地図に追加することも、ウェブページに直接埋め込むこともできます。次のコード例は、Autocomplete ウィジェットをマップ コントロールとして埋め込む方法を示しています。

  • Autocomplete ウィジェット コンストラクタは次の 2 つの引数を取ります。
    • タイプが text の HTML input 要素。これは、オートコンプリート サービスが監視し、結果を付加する入力フィールドです。
    • 省略可能な AutocompleteOptions 引数。クエリを制限する追加オプションを指定できます。
  • 境界を設定するには、autocomplete.bindTo() を呼び出して Autocomplete インスタンスを地図に明示的にバインドします。
  • 自動入力のオプションで、場所データのフィールドを指定します。
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapTypeControl: false,
  });
  const card = document.getElementById("pac-card");
  const input = document.getElementById("pac-input");
  const options = {
    fields: ["formatted_address", "geometry", "name"],
    strictBounds: false,
  };

  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

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

  // Bind the map's bounds (viewport) property to the autocomplete object,
  // so that the autocomplete requests use the current map bounds for the
  // bounds option in the request.
  autocomplete.bindTo("bounds", map);

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

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

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

Place Autocomplete ウィジェット(新版)

Place クラスには、HTMLElement サブクラスである PlaceAutocompleteElement があります。これは、マップ コントロールとして地図に追加したり、ウェブページに直接埋め込んだりできる UI コンポーネントを提供します。次のコード例は、PlaceAutocompleteElement ウィジェットを地図コントロールとして埋め込む方法を示しています。

Place Autocomplete ウィジェットは次のように改良されています。

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

実装の主な違いは次のとおりです。

  • クエリ予測は Autocomplete クラスでは使用できません。
  • PlaceAutocompleteElementPlaceAutocompleteElementOptions を使用して作成されます。
  • プレースデータ フィールドは、選択時(fetchFields() が呼び出されるとき)に指定されます。
  • locationBounds オプションまたは locationRestriction オプションを使用して境界を設定します。
  • id 属性(HTMLElement から継承)を使用して、PlaceAutocompleteElement を HTML テキスト入力要素に関連付けます。
let map;
let marker;
let infoWindow;

async function initMap() {
  // Request needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("marker"),
    google.maps.importLibrary("places"),
  ]);

  // Initialize the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapId: "4504f8b37365c3d0",
    mapTypeControl: false,
  });

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

  placeAutocomplete.id = "place-autocomplete-input";
  const card = document.getElementById("place-autocomplete-card");

  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

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

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

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    anchor: marker,
    shouldFocus: false,
  });
}