Place Autocomplete-Daten-API

Mit der Place Autocomplete Data API können Sie Ortsvorschläge programmatisch abrufen, um benutzerdefinierte automatische Vervollständigungen mit mehr Kontrolle zu erstellen, als das mit dem Widget für die automatische Vervollständigung möglich ist. In diesem Leitfaden erfahren Sie, wie Sie mit der Place Autocomplete Data API Anfragen zur automatischen Vervollständigung basierend auf Nutzerabfragen stellen.

Das folgende Beispiel zeigt eine einfache Einbindung mit automatischer Vervollständigung. Geben Sie Ihre Suchanfrage ein und klicken Sie dann, um das gewünschte Ergebnis auszuwählen.

Autocomplete-Anfragen

Eine Anfrage zur automatischen Vervollständigung verwendet einen Abfrage-Eingabestring und gibt eine Liste mit Ortsvorschlägen zurück. Wenn Sie eine Anfrage zur automatischen Vervollständigung stellen möchten, rufen Sie fetchAutocompleteSuggestions() auf und übergeben Sie eine Anfrage mit den erforderlichen Attributen. Das Attribut input enthält den zu suchenden String. In einer typischen Anwendung wird dieser Wert aktualisiert, wenn der Nutzer eine Abfrage eingibt. Die Anfrage sollte eine sessionToken enthalten, die zu Abrechnungszwecken verwendet wird.

Das folgende Snippet zeigt, wie Sie einen Anfragetext erstellen, ein Sitzungstoken hinzufügen und dann fetchAutocompleteSuggestions() aufrufen, 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.

Wenn Sie die Ergebnisse einschränken, ignoriert das Autocomplete-Widget alle Ergebnisse, die außerhalb des Einschränkungsbereichs 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.

Mit der Eigenschaft origin können Sie den Startpunkt angeben, von dem aus die geodätische Entfernung zum Ziel berechnet werden soll. Wenn dieser Wert weggelassen wird, wird die Entfernung nicht zurückgegeben.

Mit der Property includedPrimaryTypes kannst du bis zu fünf Ortstypen angeben. Wenn keine Typen angegeben sind, werden Orte aller Typen zurückgegeben.

Siehe API-Referenz

Ortsdetails abrufen

Wenn Sie ein Place-Objekt aus einem Ortsvorschlagsergebnis zurückgeben möchten, rufen Sie zuerst toPlace() auf. Rufen Sie dann fetchFields() für das resultierende Place-Objekt auf. Die Sitzungs-ID aus der Ortsvervollständigung ist automatisch enthalten. Durch den Aufruf von fetchFields() wird die automatische Vervollständigung 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 Nutzersuche mit automatischer Vervollständigung zu Abrechnungszwecken in einer separaten Sitzung zusammen. Die Sitzung beginnt, sobald der Nutzer mit der Eingabe beginnt. Die Sitzung wird beendet, wenn der Nutzer einen Ort auswählt und die Funktion „Place Details“ aufgerufen wird.

Wenn Sie ein neues Sitzungstoken erstellen und einer Anfrage hinzufügen möchten, erstellen Sie eine Instanz von AutocompleteSessionToken. Legen Sie dann das Attribut sessionToken der Anfrage so fest, dass die Tokens verwendet werden, 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 Instanz Place erstellt haben, müssen Sie das Sitzungstoken nicht an fetchFields() übergeben, da dies automatisch erfolgt.

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

Legen Sie ein Sitzungstoken für die nächste Sitzung fest. Erstellen Sie dazu eine neue Instanz von AutocompleteSessionToken.

Empfehlungen für Sitzungstokens:

  • Verwenden Sie für alle „Place Autocomplete“-Aufrufe Sitzungstokens.
  • Generieren Sie für jede Sitzung ein neues Token.
  • Übergeben Sie für jede neue Sitzung ein eindeutiges Sitzungstoken. Wenn Sie dasselbe Token für mehr als eine Sitzung verwenden, wird jede Anfrage einzeln abgerechnet.

Sie können das Sitzungstoken für die automatische Vervollständigung in einer Anfrage auch weglassen. Ohne das Sitzungstoken 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 in Rechnung gestellt, als wäre kein Sitzungstoken angegeben worden.

Beispiel

Wenn der Nutzer eine Abfrage eingibt, wird nach wenigen Tastenanschlägen (nicht pro Zeichen) eine Anfrage zur automatischen Vervollständigung aufgerufen. Daraufhin wird eine Liste möglicher Ergebnisse zurückgegeben. Wenn der Nutzer eine Auswahl in der Ergebnisliste trifft, wird diese als Anfrage gezählt. Alle während der Suche gestellten Anfragen werden gebündelt und als einzelne Anfrage gezählt. Wenn der Nutzer einen Ort auswählt, ist die Suchanfrage kostenlos und nur die Ortsdatenanfrage wird berechnet. Tut er innerhalb weniger Minuten nach Beginn der Sitzung keine Auswahl, wird nur die Suchanfrage berechnet.

Aus der Perspektive einer App verläuft der Ereignisfluss wie folgt:

  1. Ein Nutzer beginnt mit der Eingabe einer Suchanfrage, um nach „Paris, Frankreich“ zu suchen.
  2. Nach der Erkennung einer Nutzereingabe erstellt die App ein neues Sitzungstoken, nämlich „Token A“.
  3. Während der Nutzer tippt, führt die API alle paar Zeichen eine Anfrage zur automatischen Vervollständigung aus und zeigt jeweils eine neue Liste mit möglichen Ergebnissen an:
    „P“
    „Par“
    „Paris“,
    „Paris, Fr“
  4. Wenn der Nutzer eine Auswahl trifft:
    • Alle aus der Abfrage resultierenden Anfragen werden gruppiert und als einzelne Anfrage der Sitzung hinzugefügt, die durch „Token A“ dargestellt wird.
    • 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 das Token A.
Weitere Informationen zur Abrechnung von Sitzungen

Vollständiges Codebeispiel

Dieser Abschnitt enthält vollständige Beispiele, die die Verwendung des Place Autocomplete Data API veranschaulichen .

Vervollständigungen bei der automatischen Vervollständigung von Orten

Im folgenden Beispiel wird gezeigt, wie fetchAutocompleteSuggestions() für die Eingabe „Tadi“, dann toPlace() für das erste Vorhersageergebnis und dann ein Aufruf von fetchFields() zum Abrufen von Ortsdetails aufgerufen wird.

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 bei Sitzungen mit automatischer Vervollständigung einfügen

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

TypeScript

let title;
let results;
let input;
let token;

// Add an initial request body.
let 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",
};

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

    title = document.getElementById('title');
    results = document.getElementById('results');
    input = document.querySelector("input");
    input.addEventListener("input", makeAcRequest);
    request = refreshToken(request) as any;
}

async function makeAcRequest(input) {
    // Reset elements and exit if an empty string is received.
    if (input.target.value == '') {
        title.innerText = '';
        results.replaceChildren();
        return;
    }

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

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

    title.innerText = 'Query predictions for "' + request.input + '"';

    // Clear the list first.
    results.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 element.
        const li = document.createElement('li');
        li.appendChild(a);
        results.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    let placeText = document.createTextNode(place.displayName + ': ' + place.formattedAddress);
    results.replaceChildren(placeText);
    title.innerText = 'Selected Place:';
    input.value = '';
    refreshToken(request);
}

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

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

JavaScript

let title;
let results;
let input;
let token;
// Add an initial request body.
let 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",
};

async function init() {
  token = new google.maps.places.AutocompleteSessionToken();
  title = document.getElementById("title");
  results = document.getElementById("results");
  input = document.querySelector("input");
  input.addEventListener("input", makeAcRequest);
  request = refreshToken(request);
}

async function makeAcRequest(input) {
  // Reset elements and exit if an empty string is received.
  if (input.target.value == "") {
    title.innerText = "";
    results.replaceChildren();
    return;
  }

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

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

  title.innerText = 'Query predictions for "' + request.input + '"';
  // Clear the list first.
  results.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 element.
    const li = document.createElement("li");

    li.appendChild(a);
    results.appendChild(li);
  }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  let placeText = document.createTextNode(
    place.displayName + ": " + place.formattedAddress,
  );

  results.replaceChildren(placeText);
  title.innerText = "Selected Place:";
  input.value = "";
  refreshToken(request);
}

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

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=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Testbeispiel