Place Autocomplete Data API

Entwickler im Europäischen Wirtschaftsraum (EWR)

Mit der Place Autocomplete Data API können Sie Vorhersagen zu Orten programmatisch abrufen, um benutzerdefinierte Funktionen für die automatische Vervollständigung zu erstellen, die sich besser steuern lassen als das Widget für die automatische Vervollständigung. In diesem Leitfaden erfahren Sie, wie Sie die Place Autocomplete Data API verwenden, um Vorschlagsanfragen basierend auf Nutzeranfragen zu stellen.

Das folgende Beispiel zeigt eine vereinfachte Autocomplete-Integration. Geben Sie Ihren Suchbegriff ein, z. B. „Pizza“ oder „Poke“, und klicken Sie dann auf das gewünschte Ergebnis.

Autocomplete-Anfragen

Bei einer Autocomplete-Anfrage wird ein Eingabestring für die Abfrage verwendet und eine Liste mit Ortsvorschlägen zurückgegeben. Rufen Sie zum Senden einer Autocomplete-Anfrage fetchAutocompleteSuggestions() auf und übergeben Sie eine Anfrage mit den erforderlichen Attributen. Die Eigenschaft input enthält den Suchstring. In einer typischen Anwendung wird dieser Wert aktualisiert, während der Nutzer eine Anfrage eingibt. Die Anfrage sollte ein sessionToken enthalten, das für Abrechnungszwecke verwendet wird.

Im folgenden Snippet wird gezeigt, wie ein Anfragetext erstellt und ein Sitzungstoken hinzugefügt wird. Anschließend wird fetchAutocompleteSuggestions() aufgerufen, um eine Liste von PlacePredictions abzurufen.

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

Automatische Vervollständigung einschränken

Standardmäßig zeigt Place Autocomplete sämtliche Ortstypen an. Dabei werden die Vorschläge nach der Nähe zum Nutzerstandort gewichtet. Es werden alle verfügbaren Datenfelder für den vom Nutzer ausgewählten Ort abgerufen. Sie können die Optionen für Place Autocomplete so festlegen, dass relevantere Vorschläge angezeigt werden. Dazu schränken Sie die Ergebnisse ein oder wenden eine Gewichtung an.

Werden die Ergebnisse eingeschränkt, ignoriert das Autocomplete-Widget alle Ergebnisse, die außerhalb des festgelegten Bereichs liegen. Häufig werden die Ergebnisse auf die Kartengrenzen beschränkt. Wenn Sie eine Gewichtung anwenden, zeigt das Autocomplete-Widget Ergebnisse innerhalb des angegebenen Bereichs an, einige können jedoch auch außerhalb liegen.

Verwenden Sie das Attribut origin, um den Ausgangspunkt anzugeben, von dem aus die geodätische Entfernung zum Ziel berechnet werden soll. Wenn dieser Wert weggelassen wird, wird die Entfernung nicht zurückgegeben.

Verwenden Sie das Attribut includedPrimaryTypes, um bis zu fünf Ortstypen anzugeben. Wenn keine Typen angegeben sind, werden Orte aller Typen zurückgegeben.

API-Referenz

Ortsdetails abrufen

Wenn Sie ein Place-Objekt aus einem Ergebnis der Ortsvorhersage zurückgeben möchten, rufen Sie zuerst toPlace() und dann fetchFields() für das resultierende Place-Objekt auf. Die Sitzungs-ID aus der Ortsvorhersage wird automatisch eingefügt. Wenn Sie fetchFields() anrufen, wird die Autocomplete-Sitzung beendet.

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;

Sitzungstokens

Sitzungstokens fassen die Abfrage- und Auswahlphasen einer Nutzeranfrage zur automatischen Vervollständigung zu Abrechnungszwecken zu einer separaten Sitzung zusammen. Die Sitzung beginnt, wenn der Nutzer mit der Eingabe beginnt. Die Sitzung wird beendet, wenn der Nutzer einen Ort auswählt und ein „Place Details“-Aufruf ausgeführt wird.

Wenn Sie ein neues Sitzungstoken erstellen und einer Anfrage hinzufügen möchten, erstellen Sie eine Instanz von AutocompleteSessionToken und legen Sie dann die Eigenschaft sessionToken der Anfrage fest, um die Tokens zu verwenden, wie im folgenden Snippet gezeigt:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Eine Sitzung wird beendet, wenn fetchFields() aufgerufen wird. Nachdem Sie die Place-Instanz erstellt haben, müssen Sie das Sitzungstoken nicht an fetchFields() übergeben, da dies automatisch erfolgt.

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

Erstellen Sie ein Sitzungstoken für die nächste Sitzung, indem Sie eine neue Instanz von AutocompleteSessionToken erstellen.

Empfehlungen für Sitzungstokens:

  • Verwenden Sie Sitzungstokens für alle Place Autocomplete-Aufrufe.
  • Generieren Sie für jede Sitzung ein neues Token.
  • Für jede neue Sitzung muss ein eindeutiges Sitzungstoken weitergegeben werden. Wenn Sie dasselbe Token für mehr als eine Sitzung verwenden, wird jede Anfrage separat in Rechnung gestellt.

Sie können das Autocomplete-Sitzungstoken optional aus einer Anfrage weglassen. Wenn das Sitzungstoken weggelassen wird, wird jede Anfrage separat abgerechnet und die SKU Autocomplete – Per Request wird ausgelöst. Wenn Sie ein Sitzungstoken wiederverwenden, wird die Sitzung als ungültig betrachtet und die Anfragen werden so berechnet, als wäre kein Sitzungstoken angegeben worden.

Beispiel

Während der Nutzer eine Anfrage eingibt, wird alle paar Tastendrücke (nicht pro Zeichen) eine Autocomplete-Anfrage aufgerufen und eine Liste möglicher Ergebnisse zurückgegeben. Wenn der Nutzer eine Auswahl aus der Ergebnisliste trifft, wird die Auswahl als Anfrage gezählt. Alle Anfragen, die während der Suche gestellt werden, werden gebündelt und als eine einzelne Anfrage gezählt. Wenn der Nutzer einen Ort auswählt, ist die Suchanfrage kostenlos. Es wird nur die Anfrage für Ortsdaten berechnet. Wenn der Nutzer nicht innerhalb weniger Minuten nach Beginn der Sitzung eine Auswahl trifft, wird nur die Suchanfrage in Rechnung gestellt.

Aus Sicht einer App sieht der Ereignisfluss so aus:

  1. Ein Nutzer beginnt mit der Eingabe einer Suchanfrage nach „Paris, Frankreich“.
  2. Wenn die App eine Nutzereingabe erkennt, wird ein neues Sitzungstoken erstellt, „Token A“.
  3. Während der Nutzer tippt, sendet die API alle paar Zeichen eine Autocomplete-Anfrage und zeigt für jede Anfrage eine neue Liste potenzieller Ergebnisse an:
    „B“
    „Ber“
    „Berlin“
    „Berlin, D“
  4. Wenn der Nutzer eine Auswahl trifft:
    • Alle Anfragen, die aus der Abfrage resultieren, werden gruppiert und der Sitzung, die durch „Token A“ dargestellt wird, als einzelne Anfrage hinzugefügt.
    • Die Auswahl des Nutzers wird als „Place Details“-Anfrage gezählt und der Sitzung hinzugefügt, die durch „Token A“ dargestellt wird.
  5. Die Sitzung wird beendet und die App verwirft „Token A“.
Weitere Informationen zur Abrechnung von Sitzungen

Vollständiges Codebeispiel

Dieser Abschnitt enthält vollständige Beispiele für die Verwendung der Place Autocomplete Data API .

Automatische Vervollständigungen für Orte

Im folgenden Beispiel wird fetchAutocompleteSuggestions() für die Eingabe „Tadi“ aufgerufen. Anschließend wird toPlace() für das erste Vorhersageergebnis aufgerufen, gefolgt von einem Aufruf von fetchFields(), um Ortsdetails abzurufen.

TypeScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
    // @ts-ignore
    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 + '":'));

    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a new list element.
        const listItem = document.createElement('li');
        const resultsElement = document.getElementById("results") as HTMLElement;
        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

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
  // @ts-ignore
  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 + '":'),
  );

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a new list element.
    const listItem = document.createElement("li");
    const resultsElement = document.getElementById("results");

    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>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 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: "weekly"});</script>
  </body>
</html>

Testbeispiel

Automatische Vervollständigung von Orten mit Sitzungen

In diesem Beispiel wird gezeigt, wie fetchAutocompleteSuggestions() auf Grundlage von Nutzeranfragen aufgerufen wird, wie eine Liste mit vorhergesagten Orten als Antwort angezeigt wird und wie schließlich Ortsdetails für den ausgewählten Ort abgerufen werden. Das Beispiel zeigt auch die Verwendung von Sitzungstokens, um eine Nutzeranfrage mit der endgültigen „Place Details“-Anfrage zu gruppieren.

TypeScript

let titleElement;
let resultsContainerElement;
let inputElement;

let newestRequestId = 0;

// Add an initial request body.
const request = {
    input: '',
    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',
};

function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}

async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;

    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Query predictions for "${request.input}"`;

    // Clear the list first.
    resultsContainerElement.replaceChildren();

    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a link for the place, add an event handler to fetch the place.
        const a = document.createElement('a');
        a.addEventListener('click', () => {
            onPlaceSelected(placePrediction!.toPlace());
        });
        a.innerText = placePrediction!.text.toString();

        // Create a new list item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}

// Helper function to refresh the session token.
function refreshToken(request) {
    // Create a new session token and add it to the request.
    request.sessionToken = new google.maps.places.AutocompleteSessionToken();
}

declare global {
    interface Window {
      init: () => void;
    }
  }
  window.init = init;

JavaScript

let titleElement;
let resultsContainerElement;
let inputElement;
let newestRequestId = 0;
// Add an initial request body.
const request = {
    input: '',
    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',
};
function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}
async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }
    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;
    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId)
        return;
    titleElement.innerText = `Query predictions for "${request.input}"`;
    // Clear the list first.
    resultsContainerElement.replaceChildren();
    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;
        // Create a link for the place, add an event handler to fetch the place.
        const a = document.createElement('a');
        a.addEventListener('click', () => {
            onPlaceSelected(placePrediction.toPlace());
        });
        a.innerText = placePrediction.text.toString();
        // Create a new list item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}
// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}
// Helper function to refresh the session token.
function refreshToken(request) {
    // Create a new session token and add it to the request.
    request.sessionToken = new google.maps.places.AutocompleteSessionToken();
}
window.init = 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;
}

a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

input {
  width: 300px;
}

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>
  </head>
  <body>
    <input id="input" type="text" placeholder="Search for a place..." />
    <div id="title"></div>
    <ul id="results"></ul>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Testbeispiel