Widżet autouzupełniania miejsca (podgląd)

Widżet autouzupełniania miejsc tworzy pole do wprowadzania tekstu, dostarcza prognozy miejsc do listy wyboru w interfejsie i zwraca szczegóły miejsca w odpowiedzi na wybór użytkownika. Użyj widżetu autouzupełniania miejsca, aby umieścić na swojej stronie internetowej kompletny, samodzielny interfejs autouzupełniania.

Wymagania wstępne

Aby korzystać z autouzupełniania miejsc (wersja testowa), musisz włączyć interfejs „Places API” w projekcie Google Cloud i określić kanał wersji beta (v: "beta") w module wczytywania. Więcej informacji znajdziesz w artykule Pierwsze kroki.

Co nowego

Autouzupełnianie miejsc (podgląd) zostało ulepszone na kilka sposobów:

  • Interfejs widżetu autouzupełniania obsługuje lokalizację regionalną (w tym języki RTL), obiekt zastępczy do wprowadzania tekstu, logo listy prognoz i prognozowanych miejsc.
  • Ulepszone ułatwienia dostępu, w tym obsługa czytników ekranu i interakcji z klawiaturą.
  • Widżet autouzupełniania zwraca nową klasę Place, aby uprościć obsługę zwróconego obiektu.
  • Lepsza obsługa urządzeń mobilnych i małych ekranów.
  • Większa wydajność i lepszy wygląd grafiki.

Dodawanie widżetu autouzupełniania

Widżet autouzupełniania możesz dodać do strony internetowej lub mapy Google. Widżet autouzupełniania tworzy pole do wprowadzania tekstu, dostarcza prognozy dotyczące miejsc na liście wyboru interfejsu i zwraca szczegóły miejsca w odpowiedzi na kliknięcie przez użytkownika za pomocą detektora gmp-placeselect. W tej sekcji dowiesz się, jak dodać widżet autouzupełniania do strony internetowej lub Map Google.

Dodawanie widżetu autouzupełniania do strony internetowej

Aby dodać widżet autouzupełniania do strony internetowej, utwórz nowy obiekt google.maps.places.PlaceAutocompleteElement i dołącz go do strony, jak w tym przykładzie:

TypeScript

// Request needed libraries.
//@ts-ignore
const [{ Map }] = await Promise.all([
    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);

JavaScript

// Request needed libraries.
//@ts-ignore
const [{ Map }] = await Promise.all([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);

Zobacz cały przykładowy kod

Dodawanie widżetu autouzupełniania do mapy

Aby dodać widżet autouzupełniania do mapy, utwórz nowe wystąpienie google.maps.places.PlaceAutocompleteElement, dołącz PlaceAutocompleteElement do obiektu div i wypchnij go na mapę jako element sterujący, jak pokazano w tym przykładzie:

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

Zobacz cały przykładowy kod

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.

Ogranicz wyszukiwanie miejsc według kraju

Aby ograniczyć wyszukiwanie miejsc do jednego lub kilku konkretnych krajów, użyj właściwości componentRestrictions do określenia kodów krajów, tak jak w tym fragmencie:

const pac = new google.maps.places.PlaceAutocompleteElement({
  componentRestrictions: {country: ['us', 'au']},
});

Ogranicz wyszukiwanie miejsc do granic mapy

Aby ograniczyć wyszukiwanie miejsc tylko do granic mapy, dodaj granice za pomocą właściwości locationRestrictions, jak pokazano w tym fragmencie:

const pac = new google.maps.places.PlaceAutocompleteElement({
  locationRestriction: map.getBounds(),
});

Gdy ograniczasz obszar do granic mapy, dodaj detektor, aby aktualizować granice, gdy się zmienią:

map.addListener('bounds_changed', () => {
  autocomplete.locationRestriction = map.getBounds();
});

Aby usunąć przycisk locationRestriction, ustaw go na null.

Uprzedzenia wyników wyszukiwania miejsc

Uprzedź wyniki wyszukiwania względem obszaru koła, używając właściwości locationBias i przekazując promień w ten sposób:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}},
});

Aby usunąć przycisk locationBias, ustaw go na null.

Ograniczanie wyników wyszukiwania miejsc do określonych typów

Ogranicz wyniki wyszukiwania miejsc do określonych typów miejsc, używając właściwości types i określając jeden lub więcej typów miejsc, jak pokazano poniżej:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  types: ['establishment'],
});

Pełną listę obsługiwanych typów znajdziesz w tabeli 3. Typy obsługiwanych w żądaniach autouzupełniania miejsc.

Pobierz informacje o miejscu

Aby uzyskać szczegółowe informacje o wybranym miejscu, dodaj do zdarzenia PlaceAutocompleteElement detektor gmp-place-select, jak pokazano w tym przykładzie:

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,
  );
});

Zobacz cały przykładowy kod

W poprzednim przykładzie detektor zdarzeń zwraca obiekt klasy Place. Zadzwoń pod numer place.fetchFields(), aby pobrać pola danych dotyczące informacji o miejscu potrzebne w zgłoszeniu.

Z następnego przykładu odbiornik wysyła żądanie informacji o miejscu i wyświetla je na mapie.

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;
});

Zobacz cały przykładowy kod

Pobierz wyniki geokodowania dla wybranego miejsca

Aby uzyskać wyniki geokodowania dla wybranego miejsca, użyj parametru google.maps.Geocoder, aby określić lokalizację, jak w tym fragmencie kodu:

const map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 50.064192, lng: -130.605469},
  zoom: 3,
});

const marker = new google.maps.Marker({map});
const autocomplete = new google.maps.places.PlaceAutocompleteElement();
const geocoder = new google.maps.Geocoder();

autocomplete.addListener('gmp-placeselect', async ({prediction: place}) => {
  const results = await geocoder.geocode({place.id});
  marker.setPlace({
    placeId: place.id,
    location: results[0].geometry.location,
  });
});

Przykładowe mapy

Ta sekcja zawiera pełny kod do przykładowych map przedstawionych na tej stronie.

Element autouzupełniania

W tym przykładzie dodajesz do strony internetowej widżet autouzupełniania i wyświetlają wyniki dla każdego wybranego miejsca.

TypeScript

async function initMap(): Promise<void> {
    // Request needed libraries.
    //@ts-ignore
    const [{ Map }] = await Promise.all([
        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();

JavaScript

async function initMap() {
  // Request needed libraries.
  //@ts-ignore
  const [{ Map }] = await Promise.all([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>

Zobacz próbkę

Autouzupełnianie mapy

Ten przykład pokazuje, jak dodać widżet autouzupełniania do mapy Google.

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>

Zobacz próbkę

Użycie komponentu Selektor miejsc

Uwaga: ten przykład korzysta z biblioteki typu open source. W README znajdziesz pomoc i komentarze dotyczące biblioteki.

Komponent wyboru miejsc to pole tekstowe, które pozwala użytkownikom wyszukać konkretny adres lub miejsce przy użyciu autouzupełniania. Jest to część rozszerzonej biblioteki komponentów internetowych, czyli zestawu komponentów internetowych, które pomagają programistom szybciej tworzyć lepsze mapy i funkcje lokalizacji.

Konfigurator selektora miejsc

Użyj konfiguratora, aby utworzyć kod możliwy do umieszczenia dla niestandardowego komponentu selektora miejsc, a następnie wyeksportuj go do wykorzystania z popularnymi platformami, takimi jak React i Angular, lub z brakującą platformą.

Rozpocznij

Zacznij od wczytania biblioteki komponentów rozszerzonych przy użyciu npm.

Aby uzyskać najlepszą wydajność, użyj menedżera pakietów i zaimportuj tylko potrzebne komponenty. Ten pakiet jest podany w npm jako @googlemaps/extended-component-library. Zainstaluj ją za pomocą:

  npm i @googlemaps/extended-component-library;

Następnie zaimportuj wszystkie komponenty, których używasz w aplikacji.

  import '@googlemaps/extended-component-library/place_picker.js';

Po wczytaniu biblioteki npm uzyskaj klucz interfejsu API z konsoli Cloud.

  <gmpx-api-loader key="YOUR_API_KEY" solution-channel="GMP_DOCS_placepicker_v1"></gmpx-api-loader>

Użyj tagu komponentu selektora miejsc.

  <gmpx-place-picker placeholder="Enter a place" id="place-picker" style="width: 100%">
  </gmpx-place-picker>

Więcej informacji znajdziesz w GitHubie lub npm. Aby zobaczyć komponenty użyte w przykładowym kodzie, otwórz stronę z przykładami w GitHubie.