Interfejs Place Autocomplete Data API

Interfejs Place Autocomplete Data API umożliwia automatyczne pobieranie prognoz miejsc. Pozwala to na tworzenie 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ższy przykład przedstawia prostą integrację z wyprzedzeniem. Wpisz zapytanie i kliknij, aby wybrać odpowiedni wynik.

Prośby o autouzupełnianie

Żądanie autouzupełniania pobiera ciąg wejściowy zapytania i zwraca listę przewidywanych miejsc. Aby wysłać żądanie autouzupełniania, wywołaj metodę fetchAutocompleteSuggestions() i przekaż żądanie z odpowiednimi właściwościami. Właściwość input zawiera ciąg znaków do wyszukania. W typowej aplikacji wartość ta jest aktualizowana w miarę wpisywania zapytania przez użytkownika. Prośba powinna zawierać element sessionToken, który jest używany do rozliczeń.

Poniższy fragment kodu pokazuje, jak utworzyć treść żądania i dodać token sesji, a następnie wywołać 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;

Ograniczenie podpowiedzi autouzupełniania

Domyślnie autouzupełnianie miejsc prezentuje wszystkie typy miejsc, bierze pod uwagę prognozy dotyczące lokalizacji użytkownika i pobiera wszystkie dostępne pola danych dotyczące wybranego przez użytkownika miejsca. Ustaw opcje autouzupełniania miejsc, aby wyświetlać trafniejsze prognozy przez zawężenie wyników lub ich odchylenie.

Ograniczenie wyników powoduje, że widżet autouzupełniania ignoruje wszystkie wyniki, które znajdują się poza obszarem ograniczeń. Zwykłą praktyką jest ograniczanie wyników do granic mapy. Wskazanie wyników uwzględniających odchylenie powoduje, że widżet autouzupełniania pokazuje wyniki ze wskazanego obszaru, ale niektóre dopasowania mogą się znajdować poza tym obszarem.

Użyj właściwości origin, aby określić punkt początkowy, z którego chcesz obliczyć odległość geodezyjną do miejsca docelowego. Jeśli pominiesz tę wartość, odległość nie będzie zwracana.

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

Zobacz dokumentację API

Pobierz informacje o miejscu

Aby zwrócić obiekt Place z wyniku prognozy miejsca, najpierw wywołaj toPlace(), a następnie wywołaj fetchFields() w wynikowym obiekcie Place (identyfikator sesji z prognozy 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 przez 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 wykona wywołanie szczegółów miejsca.

Aby utworzyć nowy token sesji i dodać go do żądania, utwórz wystąpienie AutocompleteSessionToken, a następnie ustaw właściwość sessionToken żądania tak, aby używała tokenów w sposób pokazany w tym fragmencie:

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

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

Sesja kończy się, gdy wywoływane jest wywołanie fetchFields(). Po utworzeniu instancji Place nie musisz już przekazywać tokena sesji do fetchFields(), ponieważ odbywa się to automatycznie.

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

Aby zrobić to na potrzeby następnej sesji, utwórz nową instancję AutocompleteSessionToken.

Rekomendacje dotyczące tokenów sesji:

  • Używaj tokenów sesji dla wszystkich wywołań autouzupełniania miejsc.
  • Generuj nowy token dla każdej sesji.
  • Przekazać unikalny token sesji dla każdej nowej sesji. Używanie tego samego tokena w więcej niż 1 sesji spowoduje, że każde żądanie będzie rozliczane osobno.

Możesz opcjonalnie pominąć token sesji autouzupełniania w żądaniu. Jeśli token sesji zostanie pominięty, każde żądanie jest rozliczane oddzielnie, co aktywuje kod SKU Autouzupełnianie – na żądanie. Jeśli ponownie użyjesz tokena sesji, sesja zostanie uznana za nieprawidłową, a żądania są obciążane płatnościami tak, jakby nie został podany żaden token sesji.

Przykład

Gdy użytkownik wpisuje zapytanie, żądanie autouzupełniania jest wywoływane co kilka naciśnięć klawiszy (a nie na znak) i pojawia się lista możliwych wyników. Gdy użytkownik wybierze coś z listy wyników, jest to liczone 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 opłata jest naliczana tylko za żądanie danych miejsca. Jeśli użytkownik nie dokona wyboru w ciągu kilku minut od rozpoczęcia sesji, naliczana jest opłata tylko za wyszukiwane hasło.

Z perspektywy aplikacji przepływ zdarzeń 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 zapytanie, interfejs API wysyła żądanie autouzupełniania co kilka znaków i wyświetla nową listę potencjalnych wyników dla każdego z nich:
    „P”,
    „Par”,
    „Paryż”,
    „Paryż, pt”
  4. Gdy użytkownik dokona wyboru:
    • Wszystkie żądania wynikające z zapytania są grupowane i dodawane do sesji reprezentowanej przez „token A” w postaci pojedynczego żądania.
    • Wybór użytkownika jest liczony jako żądanie szczegółów miejsca i dodawany do sesji reprezentowanej przez „token A”.
  5. Sesja się zakończy, a aplikacja odrzuca „Token A”.
Więcej informacji o sposobach naliczania opłat za sesje

Uzupełnij przykładowy kod

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

Podpowiedzi autouzupełniania miejsc

Poniższy przykład pokazuje wywołanie fetchAutocompleteSuggestions() dla danych wejściowych „Tadi”, a następnie wywołanie toPlace() w pierwszym wyniku prognozy i wywołanie metody 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

Wypróbuj fragment

Wstawiaj z wyprzedzeniem w autouzupełnianiu za pomocą sesji

W tym przykładzie pokazano wywołanie funkcji fetchAutocompleteSuggestions() na podstawie zapytań użytkowników, wyświetlenie listy przewidywanych miejsc w odpowiedzi i w końcu pobranie informacji o wybranym miejscu. Przykład pokazuje też użycie tokenów sesji do zgrupowania zapytania użytkownika z ostatecznym żą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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

Wypróbuj fragment