Place Autocomplete ウィジェットは、テキスト入力フィールドを作成したり、UI の選択リストに場所の候補を表示したり、ユーザーの選択に応えて場所の詳細情報を返したりします。Place Autocomplete ウィジェットを使用すると、完全な自己完結型の予測入力ユーザー インターフェースをウェブページに埋め込むことができます。
前提条件
Place Autocomplete(プレビュー版)を利用するには、ご使用の Google Cloud プロジェクトで「Places API」を有効化し、ブートストラップ ローダでベータ版チャンネル(v: "beta"
)を指定する必要があります。詳しくはスタートガイドをご覧ください。
最新情報
Place Autocomplete(プレビュー版)には、次のような改良点が盛り込まれています。
- Autocomplete ウィジェットの UI で、テキスト入力のプレースホルダ、予測リストのロゴ、場所の候補に関する地域的ローカライズ(RTL 言語対応を含む)がサポートされました。
- スクリーン リーダーやキーボード操作のサポートなど、ユーザー補助機能が強化されました。
- Autocomplete ウィジェットが返す新しいプレイスクラスにより、返されたオブジェクトの処理が簡素化されます。
- モバイル デバイスと小さな画面に対するサポートが強化されました。
- パフォーマンスとグラフィックの外観が向上しました。
Autocomplete ウィジェットを追加する
Autocomplete ウィジェットは、ウェブページまたは Google マップに追加できます。Autocomplete ウィジェットは、テキスト入力フィールドを作成し、ユーザー インターフェースの選択リストに候補となる場所を提示します。ユーザーのクリックに対するレスポンスでは、gmp-placeselect
リスナーを介して場所の詳細情報を返します。このセクションでは、Autocomplete ウィジェットをウェブページまたは Google マップに追加する方法について説明します。
Autocomplete ウィジェットをウェブページに追加する
Autocomplete ウィジェットをウェブページに追加するには、新しい google.maps.places.PlaceAutocompleteElement
を作成してページに追加します。次のコードサンプルをご覧ください。
TypeScript
// Request needed libraries. //@ts-ignore await google.maps.importLibrary("places") as google.maps.PlacesLibrary; // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete);
JavaScript
// Request needed libraries. //@ts-ignore await google.maps.importLibrary("places"); // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete);
Autocomplete ウィジェットを地図に追加する
Autocomplete ウィジェットを地図に追加するには、新しい google.maps.places.PlaceAutocompleteElement
インスタンスを作成し、PlaceAutocompleteElement
を div
に追加して、カスタム コントロールとして地図にプッシュします。次のコードサンプルをご覧ください。
TypeScript
//@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; const card = document.getElementById('place-autocomplete-card') as HTMLElement; //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
JavaScript
//@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = "place-autocomplete-input"; const card = document.getElementById("place-autocomplete-card"); //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
予測入力候補を制限する
デフォルトでは、Place Autocomplete はすべてのタイプの場所を表示します。ユーザーの現在地に近い予測を優先し、ユーザーが選択した場所について利用可能なすべてのデータ フィールドを取得します。PlaceAutocompleteElementOptions を設定すると、表示される結果を制限したり、バイアスを設定したりして、より関連性の高い候補を提示することができます。
制限を適用すると、Autocomplete ウィジェットでは指定されたエリア外の結果は無視されます。一般的な制限方法は、結果を地図の境界内のみに限定することです。バイアスを設定すると、指定されたエリア内の結果が優先的に表示されますが、条件によってはエリア外の候補も提示される場合があります。
境界または地図のビューポートを指定しない場合、API は IP アドレスからユーザーの位置を検出し、その位置を優先して結果を返します。境界は可能な限り指定しましょう。指定しなかった場合、表示される候補がユーザーごとに変化する可能性があります。また、一般的に予測精度を高めるためには、地図のパンまたはズームによって設定したような実用的なビューポート、またはデバイスの位置と半径に基づいたデベロッパーによるビューポートを提供することが重要です。半径を指定できない場合は、5 km が Place Autocomplete の有効なデフォルト値とみなされます。半径が 0 のビューポート(単一ポイント)、100 m 未満のビューポート、地球にまたがるビューポートは設定しないでください。
Place Search の結果を特定の国に限定する
Place Search の結果を 1 つ以上の国に限定するには、componentRestrictions
プロパティを使用して国コードを指定します。以下のスニペットをご覧ください。
const pac = new google.maps.places.PlaceAutocompleteElement({ componentRestrictions: {country: ['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 の結果を特定の場所のタイプに限定するには、types
プロパティを使用して、1 つ以上のタイプを指定します。コードは以下のようになります。
const autocomplete = new google.maps.places.PlaceAutocompleteElement({ types: ['establishment'], });
サポートされているタイプの一覧については、表 3: Place Autocomplete のリクエストでサポートされているタイプをご覧ください。
Place Details を取得する
選択した場所の Place Details を取得するには、gmp-placeselect
リスナーを PlaceAutocompleteElement
に追加します。以下のコードサンプルをご覧ください。
TypeScript
// Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => { 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-placeselect", 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 のデータ フィールドを取得してください。
次のサンプルのリスナーは、場所の情報をリクエストして、地図上に表示します。
TypeScript
// Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore 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; });
JavaScript
// Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore 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; });
サンプル地図
このセクションには、このページで取り上げたサンプル地図のコードの全文を掲載しています。
Autocomplete 機能付きの要素
以下のサンプルは、Autocomplete ウィジェットをウェブページに追加し、選択された各場所の結果を表示します。
TypeScript
async function initMap(): Promise<void> { // Request needed libraries. //@ts-ignore await google.maps.importLibrary("places") as google.maps.PlacesLibrary; // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore 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-placeselect', async ({ place }) => { 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. //@ts-ignore await google.maps.importLibrary("places"); // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore 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-placeselect", async ({ place }) => { 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: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script> </body> </html>
サンプルを試す
Autocomplete 機能付きの地図
以下のサンプルは、Google マップに Autocomplete ウィジェットを追加する方法を示しています。
TypeScript
let map: google.maps.Map; let marker: google.maps.marker.AdvancedMarkerElement; let infoWindow: google.maps.InfoWindow; async function initMap(): Promise<void> { // Request needed libraries. //@ts-ignore 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') as HTMLElement, { center: { lat: 40.749933, lng: -73.98633 }, zoom: 13, mapId: '4504f8b37365c3d0', mapTypeControl: false, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; const card = document.getElementById('place-autocomplete-card') as HTMLElement; //@ts-ignore 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. //@ts-ignore 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, }); } initMap();
JavaScript
let map; let marker; let infoWindow; async function initMap() { // Request needed libraries. //@ts-ignore 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, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = "place-autocomplete-input"; const card = document.getElementById("place-autocomplete-card"); //@ts-ignore 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. //@ts-ignore 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, }); } 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; } #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> </head> <body> <div class="place-autocomplete-card" id="place-autocomplete-card"> <p>Search for a place here:</p> </div> <div id="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: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script> </body> </html>
サンプルを試す
Place Picker コンポーネントを使用する
Place Picker コンポーネントは、エンドユーザーが予測入力機能を使って特定の住所や場所を検索できる、テキスト入力コンポーネントです。これは、より良い地図機能とロケーション機能を迅速に構築できるようにデベロッパーを支援する、一連のウェブ コンポーネントである Extended Component Library に含まれています。
Place Picker 構成ツールを使用すると、Place Picker のカスタム コンポーネントに埋め込み可能なコードを作成して、よく知られているフレームワーク(React や Angular など)にエクスポートして使ったり、フレームワークを一切介さずに使ったりできます。