Widżet Autouzupełniania miejsc

Deweloperzy z Europejskiego Obszaru Gospodarczego (EOG)

Widżet autouzupełniania miejsc tworzy pole wprowadzania tekstu, wyświetla prognozy miejsc na liście wyboru interfejsu i zwraca szczegóły miejsca w odpowiedzi na wybór użytkownika. Użyj widżetu autouzupełniania miejsc, aby osadzić na stronie internetowej kompletny, samodzielny interfejs autouzupełniania.

Wymagania wstępne

Aby korzystać z funkcji automatycznego uzupełniania miejsc, musisz włączyć „Places API (new)” w projekcie Google Cloud. Więcej informacji znajdziesz w artykule Pierwsze kroki.

Nowości

Usługa Autouzupełnianie miejsc została ulepszona w tych obszarach:

  • Interfejs widżetu autouzupełniania obsługuje lokalizację regionalną (w tym języki pisane od prawej do lewej) w przypadku tekstu zastępczego w polu wpisywania, logo listy prognoz i prognoz dotyczących miejsc.
  • Ulepszone ułatwienia dostępu, w tym obsługa czytników ekranu i interakcja za pomocą klawiatury.
  • Widżet autouzupełniania zwraca nową klasę Place, aby uprościć obsługę zwracanego obiektu.
  • Lepsza obsługa urządzeń mobilnych i małych ekranów.
  • Lepsza wydajność i lepszy wygląd graficzny.

Dodawanie widżetu autouzupełniania

Widżet autouzupełniania tworzy pole wprowadzania tekstu, wyświetla prognozy miejsc na liście wyboru w interfejsie i zwraca szczegóły miejsca w odpowiedzi na kliknięcie użytkownika za pomocą słuchacza gmp-select. W tej sekcji dowiesz się, jak dodać widżet autouzupełniania do strony internetowej lub mapy Google.

Dodawanie widżetu autouzupełniania do strony internetowej

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

TypeScript

// Request needed libraries.
await google.maps.importLibrary("places") as google.maps.PlacesLibrary;
// 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.
await 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 pełny przykład kodu

Dodawanie widżetu autouzupełniania do mapy

Jeśli Twój adres rozliczeniowy znajduje się poza Europejskim Obszarem Gospodarczym, możesz też używać widżetu Autouzupełnianie z Mapą Google.

Aby dodać do mapy widżet autouzupełniania, utwórz nową instancję google.maps.places.PlaceAutocompleteElement, dołącz PlaceAutocompleteElement do div i dodaj ją do mapy jako niestandardowy 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';
placeAutocomplete.locationBias = center;

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';
placeAutocomplete.locationBias = center;
const card = document.getElementById('place-autocomplete-card');
//@ts-ignore
card.appendChild(placeAutocomplete);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

Zobacz pełny przykład kodu

Ograniczanie podpowiedzi autouzupełniania

Domyślnie autouzupełnianie miejsc wyświetla wszystkie typy miejsc, z większym prawdopodobieństwem prognozowania w pobliżu lokalizacji użytkownika, i pobiera wszystkie dostępne pola danych dla wybranego przez użytkownika miejsca. Ustaw PlaceAutocompleteElementOptions, aby wyświetlać trafniejsze prognozy, ograniczając lub faworyzując wyniki.

Ograniczenie wyników powoduje, że widżet autouzupełniania ignoruje wszystkie wyniki, które znajdują się poza obszarem ograniczenia. Często stosowaną praktyką jest ograniczanie wyników do granic mapy. W przypadku wyników z odchyleniem widżet autouzupełniania wyświetla wyniki w określonym obszarze, ale niektóre dopasowania mogą znajdować się poza tym obszarem.

Jeśli nie podasz żadnych granic ani widoku mapy, interfejs API spróbuje wykryć lokalizację użytkownika na podstawie jego adresu IP i dostosuje wyniki do tej lokalizacji. W miarę możliwości ustawiaj granice. W przeciwnym razie różni użytkownicy mogą otrzymywać różne prognozy. Aby ogólnie poprawić prognozy, ważne jest też podanie rozsądnego obszaru widoku, np. takiego, który ustawisz, przesuwając lub powiększając mapę, albo obszaru widoku ustawionego przez dewelopera na podstawie lokalizacji urządzenia i promienia. Jeśli promień nie jest dostępny, w przypadku funkcji autouzupełniania miejsca rozsądną wartością domyślną jest 5 km. Nie ustawiaj widocznego obszaru o zerowym promieniu (pojedynczy punkt), widocznego obszaru o średnicy zaledwie kilku metrów (mniej niż 100 m) ani widocznego obszaru obejmującego cały świat.

Ograniczanie wyszukiwania miejsc według kraju

Aby ograniczyć wyszukiwanie miejsc do co najmniej jednego konkretnego kraju, użyj właściwości includedRegionCodes do określenia kodów krajów, jak pokazano w tym fragmencie kodu:

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

Ograniczanie wyszukiwania miejsc do granic mapy

Aby ograniczyć wyszukiwanie miejsc do granic mapy, użyj właściwości locationRestrictions, aby dodać granice, jak pokazano w tym fragmencie kodu:

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

Jeśli ograniczasz wyszukiwanie do granic mapy, dodaj odbiornik, który będzie aktualizować granice, gdy się zmienią:

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

Aby usunąć locationRestriction, ustaw wartość null.

Odchylenia w wynikach wyszukiwania miejsc

Ustawiaj priorytet wyników wyszukiwania miejsc w określonym obszarze za pomocą właściwości locationBias i przekazuj promień, jak pokazano poniżej:

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

Aby usunąć locationBias, ustaw wartość 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 includedPrimaryTypes i określając co najmniej 1 typ, jak pokazano poniżej:

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

Pełną listę obsługiwanych typów znajdziesz w tabelach A i B typów miejsc.

Pobieranie szczegółów miejsca

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

TypeScript

// Add the gmp-placeselect listener, and display the results.
//@ts-ignore
placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    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-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
    selectedPlaceTitle.textContent = 'Selected Place:';
    selectedPlaceInfo.textContent = JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2);
});

Zobacz pełny przykład kodu

W powyższym przykładzie detektor zdarzeń zwraca obiekt klasy Place. Wywołaj place.fetchFields(), aby uzyskać pola danych szczegółów miejsca potrzebne w Twojej aplikacji.

W następnym przykładzie odbiornik wysyła prośbę o informacje 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-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    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-select', async ({ placePrediction }) => {
    const place = placePrediction.toPlace();
    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 pełny przykład kodu

Przykładowe mapy

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

Element autouzupełniania

W tym przykładzie do strony internetowej dodawany jest widżet autouzupełniania, a wyniki są wyświetlane dla każdego wybranego miejsca.

TypeScript

async function initMap(): Promise<void> {
    // Request needed libraries.
    await google.maps.importLibrary("places") as google.maps.PlacesLibrary;
    // 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-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        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.
    await 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-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </body>
</html>

Wypróbuj przykład

Mapa autouzupełniania

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;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
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,
        zoom: 13,
        mapId: '4504f8b37365c3d0',
        mapTypeControl: false,
    });
    //@ts-ignore
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
    //@ts-ignore
    placeAutocomplete.id = 'place-autocomplete-input';
    placeAutocomplete.locationBias = center;

    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-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        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;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
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,
        zoom: 13,
        mapId: '4504f8b37365c3d0',
        mapTypeControl: false,
    });
    //@ts-ignore
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
    //@ts-ignore
    placeAutocomplete.id = 'place-autocomplete-input';
    placeAutocomplete.locationBias = center;
    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-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </body>
</html>

Wypróbuj przykład

Korzystanie z komponentu Wybieranie miejsca

Komponent wyboru miejsca to pole tekstowe, które umożliwia użytkownikom wyszukiwanie konkretnego adresu lub miejsca za pomocą autouzupełniania. Jest to część rozszerzonej biblioteki komponentów, czyli zestawu komponentów internetowych, które pomagają deweloperom szybciej tworzyć lepsze mapy i funkcje związane z lokalizacją.

Użyj konfiguratora selektora miejsc, aby utworzyć kod do umieszczenia niestandardowego komponentu selektora miejsc, a następnie wyeksportuj go do użycia z popularnymi platformami, takimi jak React i Angular, lub bez żadnej platformy.