Interfejs Place Autocomplete Data API

Interfejs Place Autocomplete Data API umożliwia automatyczne pobieranie prognoz dotyczących miejsc w celu tworzenia niestandardowych funkcji autouzupełniania z większą kontrolą niż w przypadku widżetu autouzupełniania. Z tego przewodnika dowiesz się, jak używać interfejsu Place Autocomplete Data API do tworzenia żądań autouzupełniania na podstawie zapytań użytkowników.

Poniżej znajduje się przykład prostej integracji pisania z wyprzedzeniem. Wpisz zapytanie i kliknij, aby wybrać odpowiedni wynik.

Żądania autouzupełniania

Żądanie autouzupełniania pobiera ciąg wejściowy zapytania i zwraca listę prognoz dotyczących miejsc. Aby utworzyć żądanie autouzupełniania, wywołaj metodę fetchAutocompleteSuggestions() i przekaż żądanie z odpowiednimi właściwościami. Właściwość input zawiera ciąg do wyszukania. W typowej aplikacji wartość ta jest aktualizowana w miarę jak użytkownik wpisuje zapytanie. Prośba powinna zawierać obiekt sessionToken, który jest używany do celów rozliczeniowych.

Ten fragment kodu pokazuje, jak utworzyć treść żądania i dodać token sesji, a następnie wywołać funkcję fetchAutocompleteSuggestions(), aby uzyskać listę 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;

Ogranicz podpowiedzi autouzupełniania

Domyślnie funkcja autouzupełniania miejsc przedstawia wszystkie typy miejsc, wyświetla podpowiedzi w pobliżu lokalizacji użytkownika i pobiera wszystkie dostępne pola danych dotyczące wybranego miejsca. Ustaw opcje autouzupełniania miejsc, aby wyświetlać trafniejsze podpowiedzi przez ograniczanie lub promowanie wyników.

Ograniczenie wyników powoduje, że widżet autouzupełniania ignoruje wszystkie wyniki, które są poza tym obszarem. Zalecaną praktyką jest ograniczanie wyników do granic mapy. Promowanie wyników sprawia, że widżet autouzupełniania wyświetla wyniki z określonego obszaru, ale niektóre dopasowania mogą znajdować się poza tym obszarem.

Użyj właściwości origin, aby określić punkt początkowy, z którego ma zostać obliczona odległość geodezyjna do miejsca docelowego. Jeśli ta wartość zostanie pominięta, odległość nie jest zwracana.

Użyj właściwości includedPrimaryTypes, aby określić maksymalnie 5 typów miejsc. Jeśli nie podasz żadnych typów, zwrócone zostaną miejsca wszystkich typów.

Zobacz dokumentację interfejsu API

Pobierz informacje o miejscu

Aby zwrócić obiekt Place z wyniku prognozy dotyczącej miejsca, najpierw wywołaj toPlace(), a następnie wywołaj fetchFields() w wynikowym obiekcie Place (identyfikator sesji z prognozy dotyczącej miejsca jest dołączany automatycznie). Wywołanie fetchFields() kończy sesję autouzupełniania.

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;

Tokeny sesji

Tokeny sesji grupują fazy zapytania i wyboru autouzupełniania wyszukiwania użytkownika w oddzielną sesję na potrzeby rozliczeń. Sesja rozpoczyna się, gdy użytkownik zaczyna pisać. Sesja kończy się, gdy użytkownik wybierze miejsce i nawiązane jest połączenie z informacjami o miejscu.

Aby utworzyć nowy token sesji i dodać go do żądania, utwórz instancję AutocompleteSessionToken, a następnie ustaw właściwość sessionToken żądania tak, aby korzystała z tokenów w następujący sposób:

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

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

Sesja kończy się w chwili wywołania metody fetchFields(). Po utworzeniu instancji Place nie musisz przekazywać tokena sesji do usługi fetchFields(), ponieważ jest to obsługiwane automatycznie.

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

Aby utworzyć token sesji dla następnej sesji, utwórz nowe wystąpienie AutocompleteSessionToken.

Rekomendacje dotyczące tokena sesji:

  • Używaj tokenów sesji dla wszystkich wywołań autouzupełniania miejsc.
  • Wygeneruj nowy token dla każdej sesji.
  • Dla każdej nowej sesji przekaż unikalny token sesji. Jeśli użyjesz tego samego tokena w więcej niż 1 sesji, każde żądanie będzie rozliczane osobno.

Opcjonalnie możesz pominąć token sesji autouzupełniania w żądaniu. W przypadku pominięcia tokena sesji każde żądanie jest rozliczane osobno, co aktywuje kod SKU Autouzupełnianie – według żądania. Jeśli użyjesz tego samego tokena sesji, sesja zostanie uznana za nieprawidłową, a za żądania będą naliczane opłaty tak, jakby żaden token sesji nie został udostępniony.

Przykład

Gdy użytkownik wpisuje zapytanie, żądanie autouzupełniania jest wywoływane co kilka naciśnięć klawiszy (a nie po poszczególnych znakach) i zwraca listę możliwych wyników. Gdy użytkownik dokona wyboru z listy wyników, wybór liczy się jako żądanie, a wszystkie żądania zgłoszone podczas wyszukiwania są grupowane i zliczane jako jedno żądanie. Jeśli użytkownik wybierze miejsce, zapytanie jest dostępne bezpłatnie, a płatne są tylko żądania dotyczące danych dotyczących miejsc. Jeśli użytkownik nie dokona wyboru w ciągu kilku minut przed rozpoczęciem sesji, opłata zostanie naliczona tylko za zapytanie.

Przebieg zdarzeń z perspektywy aplikacji wygląda tak:

  1. Użytkownik zaczyna wpisywać zapytanie, aby wyszukać „Paryż, Francja”.
  2. Po wykryciu danych wejściowych użytkownika aplikacja tworzy nowy token sesji – „Token A”.
  3. Gdy użytkownik wpisuje tekst, interfejs API wysyła żądanie autouzupełniania co kilka znaków, wyświetlając nową listę potencjalnych wyników dla każdego z nich:
    „P”
    „Par”
    „Paryż”,
    „Paryż, pt”
  4. Gdy użytkownik dokona wyboru:
    • Wszystkie żądania pochodzące z zapytania są grupowane i dodawane do sesji reprezentowanej przez „Token A” jako pojedyncze żądanie.
    • Wybór użytkownika jest zliczany jako żądanie informacji o miejscu i dodawany do sesji reprezentowanej przez „Token A”.
  5. Sesja dobiega końca, a aplikacja odrzuca „Token A”.
Więcej informacji o naliczaniu opłat za sesje

Uzupełnij przykładowy kod

Ta sekcja zawiera pełne przykłady korzystania z interfejsu Place Autocomplete Data API .

Umieszczaj podpowiedzi autouzupełniania

Poniższy przykład pokazuje wywołanie fetchAutocompleteSuggestions() dla danych wejściowych „Tadi”, a następnie wywołanie toPlace() przy pierwszym wyniku prognozy, a następnie wywołanie fetchFields() w celu uzyskania szczegółów miejsca.

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>

Zobacz próbkę

Wstawiaj autouzupełnianie z wyprzedzeniem do wpisywania sesji

W tym przykładzie pokazujemy, jak wywoływać metodę fetchAutocompleteSuggestions() na podstawie zapytań użytkowników, wyświetlać listę przewidywanych miejsc w odpowiedzi, a następnie pobrać szczegółowe informacje o wybranym miejscu. Ten przykład pokazuje też użycie tokenów sesji do zgrupowania zapytania użytkownika z końcowym żądaniem informacji o miejscu.

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>

Zobacz próbkę