Place Autocomplete Data API を使用すると、場所の候補をプログラマティックに取得できます。そのため、Place Autocomplete ウィジェットよりもきめ細かく管理して、予測入力機能をカスタマイズできます。このガイドでは、Place Autocomplete Data API を使用して、ユーザーのクエリに基づいて予測入力リクエストを行う方法について説明します。
以下は、予測入力を簡略化した統合の例です。検索クエリ(「ピザ」や「ポケ」など)を入力し、希望の結果をクリックして選択します。
予測入力リクエスト
予測入力リクエストは、クエリ入力文字列を受け取り、場所の候補のリストを返します。予測入力リクエストを作成するには、fetchAutocompleteSuggestions() を呼び出し、必要なプロパティを含むリクエストを渡します。input プロパティには、検索する文字列が含まれます。一般的なアプリケーションでは、ユーザーがクエリを入力すると、この値が更新されます。リクエストには、課金目的で使用される sessionToken を含める必要があります。
次のスニペットは、リクエスト本文を作成してセッション トークンを追加し、fetchAutocompleteSuggestions() を呼び出して PlacePrediction のリストを取得する方法を示しています。
// Add an initial request body. let request = { input: 'Tadi', locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78, }, origin: { lat: 37.7893, lng: -122.4039 }, includedPrimaryTypes: ['restaurant'], language: 'en-US', region: 'us', }; // Create a session token. const token = new AutocompleteSessionToken(); // Add the token to the request. // @ts-ignore request.sessionToken = token;
予測入力候補を制限する
デフォルトでは、Place Autocomplete はすべてのタイプの場所を表示します。ユーザーの現在地に近い予測を優先し、ユーザーが選択した場所について利用可能なすべてのデータ フィールドを取得します。Place Autocomplete のオプションを設定すると、表示される結果を制限したり、バイアスを設定したりして、より関連性の高い候補を提示することができます。
制限を適用すると、Autocomplete ウィジェットでは指定されたエリア外の結果は無視されます。一般的な制限方法は、結果を地図の境界内のみに限定することです。バイアスを設定すると、指定されたエリア内の結果が優先的に表示されますが、条件によってはエリア外の候補も提示される場合があります。
origin プロパティを使用して、目的地点までの測地線距離を計算する出発地点を指定します。この値を省略すると、距離は返されません。
includedPrimaryTypes プロパティを使用して、最大 5 つの場所タイプを指定します。
タイプが指定されていない場合は、すべてのタイプの場所が返されます。
Place Details を取得する
場所の候補結果から Place オブジェクトを返すには、まず toPlace() を呼び出し、結果の Place オブジェクト(場所の候補からのセッション ID が自動的に含まれる)で fetchFields() を呼び出します。fetchFields() を呼び出すと、予測入力セッションが終了します。
let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place. await place.fetchFields({ fields: ['displayName', 'formattedAddress'], }); const placeInfo = document.getElementById('prediction'); placeInfo.textContent = `First predicted place: ${place.displayName}: ${place.formattedAddress}`;
セッション トークン
セッション トークンは、予測入力検索でのユーザーのクエリと選択フェーズを、請求処理のために個別のセッションにグループ化します。ユーザーが入力を開始するとセッションが開始されます。 ユーザーが場所を選択し、Place Details が呼び出されると、セッションは終了します。
新しいセッション トークンを作成してリクエストに追加するには、次のスニペットに示すように、AutocompleteSessionToken のインスタンスを作成し、トークンを使用するよう、リクエストの sessionToken プロパティを設定します。
// Create a session token. const token = new AutocompleteSessionToken(); // Add the token to the request. // @ts-ignore request.sessionToken = token;
fetchFields() が呼び出されるとセッションが終了します。Place インスタンスの作成後は、セッション トークンは自動的に処理されるため、fetchFields() に渡す必要はありません。
await place.fetchFields({ fields: ['displayName', 'formattedAddress'], });
AutocompleteSessionToken の新しいインスタンスを作成することで、次のセッションのセッション トークンを作成します。
セッション トークンの推奨事項:
- すべての Place Autocomplete 呼び出しにセッション トークンを使用します。
- セッションごとに新しいトークンを生成します。
- 新しいセッションごとに一意のセッション トークンを渡します。複数のセッションで同じトークンを使用すると、リクエストごとに課金されます。
必要に応じて、リクエストから予測入力セッション トークンを省略できます。セッション トークンを省略すると、Autocomplete - Per Request SKU がトリガーされ、各リクエストが個別に課金されます。セッション トークンを再使用すると、そのセッションは無効とみなされ、セッション トークンを渡さなかった場合と同様にリクエストが課金されます。
例
ユーザーがクエリを入力すると、キーを数回打つごとに(1 文字ずつではなく)予測入力リクエストが呼び出され、候補のリストが返されます。 ユーザーが結果リストから選択を行うと、その選択がリクエストとしてカウントされ、検索中に行われたすべてのリクエストがバンドルされて 1 つのリクエストとしてカウントされます。ユーザーが場所を選択すると、その検索クエリは料金なしで利用できます。料金が発生するのは、場所データ リクエストのみです。セッションの開始から数分以内にユーザーが選択を行わなかった場合は、検索クエリのみが課金されます。
アプリの観点では、イベントのフローは次のようになります。
- ユーザーがクエリの入力を開始し、「Paris, France」を検索します。
- アプリはユーザー入力を検出すると、新しいセッション トークン「トークン A」を作成します。
- ユーザーが入力を始めると、API が数文字ごとに予測入力リクエストを実行し、各々に新しい候補結果のリストを表示します。
"P"
"Par"
"Paris,"
"Paris, Fr"
- ユーザーが選択を行うと:
- このクエリによるすべてのリクエストはグループ化され、「トークン A」で表されるセッションに 1 つのリクエストとして追加されます。
- ユーザーの選択は Place Detail リクエストとしてカウントされ、「トークン A」で表されるセッションに追加されます。
- セッションが終了し、アプリは「トークン A」を破棄します。
コードサンプルの全文
このセクションでは、Place Autocomplete Data API の使用方法を示す完全なサンプルを紹介します。Place Autocomplete の候補
次のサンプルでは、入力「Tadi」に対して fetchAutocompleteSuggestions() を呼び出し、最初の候補結果に対して toPlace() を呼び出してから、fetchFields() を呼び出して場所の詳細を取得しています。
TypeScript
async function init() { const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = (await google.maps.importLibrary( 'places' )) as google.maps.PlacesLibrary; // Add an initial request body. let request = { input: 'Tadi', locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78, }, origin: { lat: 37.7893, lng: -122.4039 }, includedPrimaryTypes: ['restaurant'], language: 'en-US', region: 'us', }; // Create a session token. const token = new AutocompleteSessionToken(); // Add the token to the request. // @ts-ignore request.sessionToken = token; // Fetch autocomplete suggestions. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); const title = document.getElementById('title') as HTMLElement; title.appendChild( document.createTextNode( 'Query predictions for "' + request.input + '":' ) ); const resultsElement = document.getElementById('results') as HTMLElement; for (let suggestion of suggestions) { const placePrediction = suggestion.placePrediction; // Create a new list element. const listItem = document.createElement('li'); listItem.appendChild( document.createTextNode(placePrediction!.text.toString()) ); resultsElement.appendChild(listItem); } let place = suggestions[0].placePrediction!.toPlace(); // Get first predicted place. await place.fetchFields({ fields: ['displayName', 'formattedAddress'], }); const placeInfo = document.getElementById('prediction') as HTMLElement; placeInfo.textContent = `First predicted place: ${place.displayName}: ${place.formattedAddress}`; } init();
JavaScript
async function init() { const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = (await google.maps.importLibrary('places')); // Add an initial request body. let request = { input: 'Tadi', locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78, }, origin: { lat: 37.7893, lng: -122.4039 }, includedPrimaryTypes: ['restaurant'], language: 'en-US', region: 'us', }; // Create a session token. const token = new AutocompleteSessionToken(); // Add the token to the request. // @ts-ignore request.sessionToken = token; // Fetch autocomplete suggestions. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); const title = document.getElementById('title'); title.appendChild(document.createTextNode('Query predictions for "' + request.input + '":')); const resultsElement = document.getElementById('results'); for (let suggestion of suggestions) { const placePrediction = suggestion.placePrediction; // Create a new list element. const listItem = document.createElement('li'); listItem.appendChild(document.createTextNode(placePrediction.text.toString())); resultsElement.appendChild(listItem); } let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place. await place.fetchFields({ fields: ['displayName', 'formattedAddress'], }); const placeInfo = document.getElementById('prediction'); placeInfo.textContent = `First predicted place: ${place.displayName}: ${place.formattedAddress}`; } init();
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; }
HTML
<html>
<head>
<title>Place Autocomplete Data API Predictions</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>
<div id="title"></div>
<ul id="results"></ul>
<p><span id="prediction"></span></p>
<img
class="powered-by-google"
src="./powered_by_google_on_white.png"
alt="Powered by Google" />
</body>
</html>サンプルを試す
セッションを使用する Place Autocomplete の候補表示機能
この例では、次のコンセプトについて説明します。
- ユーザークエリに基づいて
fetchAutocompleteSuggestions()を呼び出し、レスポンスとして予測された場所のリストを表示します。 - セッション トークンを使用してユーザークエリと最終的な Place Details リクエストをグループ化します。
- 選択した場所の Place Details を取得してマーカーを表示します。
- コントロール スロッティングを使用して、UI 要素を
gmp-map要素にネストします。
TypeScript
const mapElement = document.querySelector('gmp-map') as google.maps.MapElement; let innerMap: google.maps.Map; let marker: google.maps.marker.AdvancedMarkerElement; let titleElement = document.querySelector('.title') as HTMLElement; let resultsContainerElement = document.querySelector('.results') as HTMLElement; let inputElement = document.querySelector('input') as HTMLInputElement; let tokenStatusElement = document.querySelector('.token-status') as HTMLElement; let newestRequestId = 0; let tokenCount = 0; // Create an initial request body. const request: google.maps.places.AutocompleteRequest = { input: '', includedPrimaryTypes: [ 'restaurant', 'cafe', 'museum', 'park', 'botanical_garden', ], }; async function init() { await google.maps.importLibrary('maps'); innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Update request center and bounds when the map bounds change. google.maps.event.addListener(innerMap, 'bounds_changed', async () => { request.locationRestriction = innerMap.getBounds(); request.origin = innerMap.getCenter(); }); inputElement.addEventListener('input', makeAutocompleteRequest); } async function makeAutocompleteRequest(inputEvent) { // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; const { AutocompleteSuggestion } = (await google.maps.importLibrary( 'places' )) as google.maps.PlacesLibrary; if (!inputEvent.target?.value) { titleElement.textContent = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = (inputEvent.target as HTMLInputElement).value; // Fetch autocomplete suggestions and show them in a list. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Place predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.replaceChildren(); for (const suggestion of suggestions) { const placePrediction = suggestion.placePrediction; if (!placePrediction) { continue; } // Create a link for the place, add an event handler to fetch the place. // We are using a button element to take advantage of its a11y capabilities. const placeButton = document.createElement('button'); placeButton.addEventListener('click', () => { onPlaceSelected(placePrediction.toPlace()); }); placeButton.textContent = placePrediction.text.toString(); placeButton.classList.add('place-button'); // Create a new list item element. const li = document.createElement('li'); li.appendChild(placeButton); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place: google.maps.places.Place) { const { AdvancedMarkerElement } = (await google.maps.importLibrary( 'marker' )) as google.maps.MarkerLibrary; await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'], }); resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`; titleElement.textContent = 'Selected Place:'; inputElement.value = ''; await refreshToken(); // Remove the previous marker, if it exists. if (marker) { marker.remove(); } // Create a new marker. marker = new AdvancedMarkerElement({ map: innerMap, position: place.location, title: place.displayName, }); // Center the map on the selected place. if (place.location) { innerMap.setCenter(place.location); innerMap.setZoom(15); } } // Helper function to refresh the session token. async function refreshToken() { const { AutocompleteSessionToken } = (await google.maps.importLibrary( 'places' )) as google.maps.PlacesLibrary; // Increment the token counter. tokenCount++; // Create a new session token and add it to the request. request.sessionToken = new AutocompleteSessionToken(); tokenStatusElement.textContent = `Session token count: ${tokenCount}`; } init();
JavaScript
const mapElement = document.querySelector('gmp-map'); let innerMap; let marker; let titleElement = document.querySelector('.title'); let resultsContainerElement = document.querySelector('.results'); let inputElement = document.querySelector('input'); let tokenStatusElement = document.querySelector('.token-status'); let newestRequestId = 0; let tokenCount = 0; // Create an initial request body. const request = { input: '', includedPrimaryTypes: [ 'restaurant', 'cafe', 'museum', 'park', 'botanical_garden', ], }; async function init() { await google.maps.importLibrary('maps'); innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Update request center and bounds when the map bounds change. google.maps.event.addListener(innerMap, 'bounds_changed', async () => { request.locationRestriction = innerMap.getBounds(); request.origin = innerMap.getCenter(); }); inputElement.addEventListener('input', makeAutocompleteRequest); } async function makeAutocompleteRequest(inputEvent) { // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; const { AutocompleteSuggestion } = (await google.maps.importLibrary('places')); if (!inputEvent.target?.value) { titleElement.textContent = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = inputEvent.target.value; // Fetch autocomplete suggestions and show them in a list. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Place predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.replaceChildren(); for (const suggestion of suggestions) { const placePrediction = suggestion.placePrediction; if (!placePrediction) { continue; } // Create a link for the place, add an event handler to fetch the place. // We are using a button element to take advantage of its a11y capabilities. const placeButton = document.createElement('button'); placeButton.addEventListener('click', () => { onPlaceSelected(placePrediction.toPlace()); }); placeButton.textContent = placePrediction.text.toString(); placeButton.classList.add('place-button'); // Create a new list item element. const li = document.createElement('li'); li.appendChild(placeButton); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place) { const { AdvancedMarkerElement } = (await google.maps.importLibrary('marker')); await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'], }); resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`; titleElement.textContent = 'Selected Place:'; inputElement.value = ''; await refreshToken(); // Remove the previous marker, if it exists. if (marker) { marker.remove(); } // Create a new marker. marker = new AdvancedMarkerElement({ map: innerMap, position: place.location, title: place.displayName, }); // Center the map on the selected place. if (place.location) { innerMap.setCenter(place.location); innerMap.setZoom(15); } } // Helper function to refresh the session token. async function refreshToken() { const { AutocompleteSessionToken } = (await google.maps.importLibrary('places')); // Increment the token counter. tokenCount++; // Create a new session token and add it to the request. request.sessionToken = new AutocompleteSessionToken(); tokenStatusElement.textContent = `Session token count: ${tokenCount}`; } init();
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-button { height: 3rem; width: 100%; background-color: transparent; text-align: left; border: none; cursor: pointer; } .place-button:focus-visible { outline: 2px solid #0056b3; border-radius: 2px; } .input { width: 300px; font-size: small; margin-bottom: 1rem; } /* Styles for the floating panel */ .controls { background-color: #fff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); font-family: sans-serif; font-size: small; margin: 12px; padding: 1rem; } .title { font-weight: bold; margin-top: 1rem; margin-bottom: 0.5rem; } .results { list-style-type: none; margin: 0; padding: 0; } .results li:not(:last-child) { border-bottom: 1px solid #ddd; } .results li:hover { background-color: #eee; }
HTML
<html>
<head>
<title>Place Autocomplete Data API Session</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="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID">
<div class="controls" slot="control-inline-start-block-start">
<input
type="text"
class="input"
placeholder="Search for a place..."
autocomplete="off" /><!-- Turn off the input's own autocomplete (not supported by all browsers).-->
<div class="token-status"></div>
<div class="title"></div>
<ol class="results"></ol>
</div>
</gmp-map>
</body>
</html>サンプルを試す
Autocomplete(新機能)の最適化
このセクションでは、Autocomplete(新版)サービスを最大限に活用するためのヒントを紹介します。
概要は次のとおりです。
- 機能的なユーザー インターフェースを最も手早く作成するには、Maps JavaScript API Autocomplete(新版)ウィジェット、Places SDK for Android Autocomplete(新版)ウィジェット、または Places SDK for iOS Autocomplete(新版)ウィジェットを使用します。
- Autocomplete(新規)のデータ フィールドの基本を理解します。
- 位置情報のバイアスと位置情報の制限のフィールドは省略可能ですが、予測入力のパフォーマンスに大きく影響する場合があります。
- エラー処理を使用して、API がエラーを返した場合に、アプリでグレースフル デグラデーションが行われるようにします。
- アプリでは、選択肢がない場合でもユーザーが操作を続行できるようにします。
費用の最適化に関するヒント
基本的な費用の最適化
Autocomplete(新版)サービスの費用を最適化するには、Place Details(新版)と Autocomplete(新版)ウィジェットのフィールド マスクを使用して、必要な Autocomplete(新版)のデータ フィールドのみを返すように設定します。
高度な費用の最適化
SKU: Autocomplete Request の料金設定を利用し、Place Details(新)の代わりに選択された場所に関する Geocoding API の結果をリクエストするためには、Autocomplete(新)のプログラマティック実装を行うことをおすすめします。次の両方に該当する場合は、リクエストあたりの料金設定と Geocoding API を組み合わせた方が、セッションあたり(セッション ベース)の料金設定よりも費用対効果が高くなります。
- ユーザーが選択した場所の緯度/経度または住所のみが必要な場合。その場合は、Geocoding API の方が、Place Details(新版)の呼び出しよりも少ないコストでこの情報を提供できます。
- ユーザーが予測結果を選択するまでの予測入力候補(新)リクエストの回数が、平均 4 回以下の場合。その場合は、リクエストあたりの料金設定の方がセッションあたりの料金設定よりも費用対効果が高くなります。
アプリケーションで、選択された予測結果の住所と緯度 / 経度以外の情報が必要ですか?
はい。その他の情報も必要です
セッション ベースの Autocomplete(新版)と Place Details(新版)を併用します。
アプリケーションで場所の名前、ビジネス ステータス、営業時間などの Place Details(新版)が必要なため、Autocomplete(新版)の実装では、セッション トークン(プログラムによる、または JavaScript、Android、iOS ウィジェットに組み込み)をセッションごとに使用する必要があります。また、リクエストする場所のデータ フィールドに応じて、該当する Places SKU も使用する必要があります。1
ウィジェット実装
セッション管理が JavaScript、Android、または iOS ウィジェットに自動的に組み込まれます。これには、選択された予測結果での Autocomplete(新版)リクエストと Place Details(新版)リクエストの両方が含まれます。必要な Autocomplete(新版)のデータ フィールドのみをリクエストするように、必ず fields パラメータを指定してください。
プログラマティック実装
Autocomplete(新版)リクエストでセッション トークンを使用します。選択された予測結果に関する Place Details(新版)をリクエストする際は、次のパラメータを含めます。
- Autocomplete(新版)レスポンスのプレイス ID
- Autocomplete(新版)リクエストで使用されるセッション トークン
- 必要な Autocomplete(新版)データ フィールドを指定する
fieldsパラメータ
いいえ。住所と場所のみが必要です
Autocomplete(新版)の使用時のパフォーマンスによっては、アプリケーションで Place Details(新版)を使用するよりも、Geocoding API を使用した方が費用対効果が高くなる場合があります。アプリケーションの予測入力(新機能)の効率は、ユーザーの入力内容や、アプリケーションが使用される場所、パフォーマンス最適化のベスト プラクティスが導入されているかどうかによって変わります。
次の質問に答えるためには、ユーザーがアプリケーション内で Autocomplete(新版)の予測を選択するまでに、平均でどのくらいの文字数を入力するのかを分析する必要があります。
ユーザーが Autocomplete(新版)の予測を選択するまでに実行されるリクエスト数は、平均で 4 回以下ですか?
○
セッション トークンを使用せずにプログラムによって Autocomplete(新機能)を実装し、選択された場所の予測で Geocoding API を呼び出します。
Geocoding API は、住所と緯度/経度の座標を提供します。Autocomplete リクエスト 4 件と、選択された場所予測に関する Geocoding API の呼び出しを合わせた料金は、Per Session Autocomplete(新規)のセッション 1 回あたりの料金よりも少ないコストです。1
パフォーマンスに関するベスト プラクティスを導入し、できるだけ少ない入力文字数でユーザーが求める情報を提供できるようすることをおすすめします。
いいえ
セッション ベースの Autocomplete(新版)と Place Details(新版)を併用します。
ユーザーが Autocomplete(新版)の予測を選択するまでに実行されるリクエスト数の平均が、セッションあたりの料金設定の費用を超えるため、Autocomplete(新版)の実装では、Autocomplete(新版)リクエストと関連する Place Details(新版)リクエストの両方で、セッションあたりのセッション トークンを使用する必要があります。1
ウィジェット実装
セッション管理が JavaScript、Android、または iOS ウィジェットに自動的に組み込まれます。これには、選択された予測結果での Autocomplete(新版)リクエストと Place Details(新版)リクエストの両方が含まれます。必要なフィールドのみをリクエストするように、必ず fields パラメータを指定してください。
プログラマティック実装
Autocomplete(新版)リクエストでセッション トークンを使用します。選択された予測結果に関する Place Details(新版)をリクエストする際は、次のパラメータを含めます。
- Autocomplete(新版)レスポンスのプレイス ID
- Autocomplete(新版)リクエストで使用されるセッション トークン
- 住所やジオメトリなどのフィールドを指定する
fieldsパラメータ
Autocomplete (New) リクエストを遅らせることを検討する
ユーザーが最初の 3 ~ 4 文字を入力するまで Autocomplete (New) リクエストを遅らせて、アプリケーションでのリクエスト数を減らすこともできます。たとえば、ユーザーが 3 文字を入力した後に、各文字に対して Autocomplete(New)リクエストを行う場合、ユーザーが 7 文字を入力して、1 件の Geocoding API リクエストを行う予測を選択すると、合計料金は 4 件の Autocomplete(New)Per Request + Geocoding の料金になります。1
リクエストを遅らせることで、プログラマティック リクエストの回数を平均 4 回以下に抑えられる場合は、高パフォーマンスで Autocomplete(新版)と Geocoding API を併用する実装に関するガイダンスをご覧ください。なお、リクエストを遅らせると、1 文字入力するたびに予測が表示されはずと考えているユーザーには、遅延と受けとられる場合もあります。
パフォーマンスに関するベスト プラクティスを導入し、できるだけ少ない入力文字数でユーザーが求める情報を提供できるようすることをおすすめします。
-
費用については、Google Maps Platform の料金リストをご覧ください。
パフォーマンスに関するベスト プラクティス
Autocomplete(新機能)のパフォーマンスを最適化するためのガイドラインは次のとおりです。
- Autocomplete(新版)実装に、国別のポリシー、場所のバイアス、言語設定(プログラマティック実装の場合)を追加します。ウィジェットはユーザーのブラウザやモバイル デバイスから言語設定を選択するため、ウィジェットでは言語設定は不要です。
- Autocomplete(新版)が地図に関連付けられている場合は、地図のビューポートを基準に場所にバイアスをかけることができます。
- ユーザーが予測入力候補(新版)のいずれも選択しなかった場合(通常は目的の住所が候補に挙がらなかったことが原因)、ユーザーの元の入力内容を再利用して、より関連性の高い結果を取得できます。
- ユーザーが住所情報のみを入力することが予想される場合は、Geocoding API の呼び出しで、ユーザーの元の入力内容を再利用します。
- ユーザーが特定の場所に関する検索語句(名前や住所)を入力することが予想される場合は、Place Details (New) リクエストを使用します。特定の地域の結果のみが求められる場合は、場所のバイアスを使用します。
- 建物内の特定のユニットやアパートの住所など、サブプレミス住所を入力するユーザー。たとえば、チェコ語の住所「Stroupežnického 3191/17, Praha」では、Autocomplete(新版)で部分的な予測が生成されます。
- ユーザーがニューヨークの「23-30 29th St, Queens」や、ハワイのカウアイ島の「47-380 Kamehameha Hwy, Kaneohe」など、道路区間のプレフィックスを入力する場合。
位置情報のバイアス
location パラメータと radius パラメータを渡すことで、バイアスを設定し、指定した範囲内の結果を優先します。これにより、定義されたエリア内の結果を優先的に表示するよう Autocomplete(新版)に指示します。指定した範囲外の結果が返されることもあります。components パラメータを使用すると、指定した国内の場所のみを表示するように結果をフィルタできます。
ロケーションの制限
locationRestriction パラメータを渡すことで、結果を指定したエリアに制限します。
locationRestriction パラメータを追加して、location パラメータと radius パラメータで定義された地域に結果を制限することもできます。これにより、その地域内の結果のみを返すように Autocomplete(新版)に指示します。