Widget di completamento automatico dei luoghi

Sviluppatori dello Spazio economico europeo (SEE)

Il widget Place Autocomplete crea un campo di input di testo, fornisce le previsioni sui luoghi in un elenco di selezione dell'interfaccia utente e restituisce i dettagli del luogo in risposta alla selezione dell'utente. Utilizza il widget Place Autocomplete per incorporare un'interfaccia utente di completamento automatico completa e autonoma nella tua pagina web.

Prerequisiti

Per utilizzare il completamento automatico dei luoghi, devi abilitare "Places API (new)" nel tuo progetto Google Cloud. Per maggiori dettagli, consulta la sezione Guida introduttiva.

Novità

Place Autocomplete è stato migliorato nei seguenti modi:

  • L'interfaccia utente del widget Completamento automatico supporta la localizzazione regionale (incluse le lingue RTL) per il segnaposto di input di testo, il logo dell'elenco dei suggerimenti e i suggerimenti sui luoghi.
  • Accessibilità migliorata, incluso il supporto per screen reader e l'interazione da tastiera.
  • Il widget Place Autocomplete restituisce la nuova classe Place per semplificare la gestione dell'oggetto restituito.
  • Supporto migliore per dispositivi mobili e schermi piccoli.
  • Prestazioni migliori e aspetto grafico migliorato.

Aggiungere un widget di completamento automatico

Il widget di completamento automatico crea un campo di input di testo, fornisce le previsioni sui luoghi in un elenco di selezione della UI e restituisce i dettagli del luogo in risposta a un clic dell'utente utilizzando il listener gmp-select. Questa sezione mostra come aggiungere un widget di completamento automatico a una pagina web o a una mappa di Google.

Aggiungere un widget di completamento automatico a una pagina web

Per aggiungere il widget di completamento automatico a una pagina web, crea un nuovo google.maps.places.PlaceAutocompleteElement e aggiungilo alla pagina come mostrato nell'esempio seguente:

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

Vedi l'esempio di codice completo

Aggiungere un widget di completamento automatico a una mappa

Se il tuo indirizzo di fatturazione non si trova nello Spazio economico europeo (SEE), puoi utilizzare anche il widget di completamento automatico con una mappa di Google.

Per aggiungere un widget di completamento automatico a una mappa, crea una nuova istanza di google.maps.places.PlaceAutocompleteElement, aggiungi PlaceAutocompleteElement a un div e inseriscilo nella mappa come controllo personalizzato, come mostrato nell'esempio seguente:

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

Vedi l'esempio di codice completo

Limitare le previsioni di completamento automatico

Per impostazione predefinita, Place Autocomplete presenta tutti i tipi di luoghi, con una preferenza per le previsioni vicino alla posizione dell'utente, e recupera tutti i campi di dati disponibili per il luogo selezionato dall'utente. Imposta PlaceAutocompleteElementOptions per presentare previsioni più pertinenti, limitando o modificando i risultati.

La limitazione dei risultati fa sì che il widget di completamento automatico ignori tutti i risultati al di fuori dell'area di limitazione. Una pratica comune è limitare i risultati ai limiti della mappa. La distorsione dei risultati fa sì che il widget di completamento automatico mostri i risultati all'interno dell'area specificata, ma alcune corrispondenze potrebbero trovarsi al di fuori di quest'area.

Se non fornisci limiti o una visualizzazione della mappa, l'API tenterà di rilevare la posizione dell'utente dal suo indirizzo IP e orienterà i risultati verso quella posizione. Imposta un limite ogni volta che è possibile. In caso contrario, utenti diversi potrebbero ricevere previsioni diverse. Inoltre, per migliorare le previsioni in generale, è importante fornire un'area visibile ragionevole, ad esempio una che hai impostato spostando o ingrandendo la mappa oppure un'area visibile impostata dallo sviluppatore in base alla posizione e al raggio del dispositivo. Quando un raggio non è disponibile, 5 km sono considerati un valore predefinito ragionevole per il completamento automatico dei luoghi. Non impostare un'area visibile con raggio zero (un singolo punto), un'area visibile di pochi metri (meno di 100 m) o un'area visibile che copre l'intero globo.

Limitare la ricerca di luoghi per paese

Per limitare la ricerca di luoghi a uno o più paesi specifici, utilizza la proprietà includedRegionCodes per specificare i codici paese, come mostrato nello snippet seguente:

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

Limitare la ricerca di luoghi ai limiti della mappa

Per limitare la ricerca di luoghi ai limiti di una mappa, utilizza la proprietà locationRestrictions per aggiungere i limiti, come mostrato nel seguente snippet:

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

Quando limiti i risultati ai confini della mappa, assicurati di aggiungere un listener per aggiornare i confini quando cambiano:

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

Per rimuovere locationRestriction, impostalo su null.

Risultati di ricerca dei luoghi con bias

Per orientare i risultati della ricerca di luoghi verso un'area circolare, utilizza la proprietà locationBias e passa un raggio, come mostrato di seguito:

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

Per rimuovere locationBias, impostalo su null.

Limitare i risultati di ricerca di luoghi a determinati tipi

Limita i risultati di ricerca di luoghi a determinati tipi di luoghi utilizzando la proprietà includedPrimaryTypes e specificando uno o più tipi, come mostrato di seguito:

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

Per un elenco completo dei tipi supportati, vedi Tabelle A e B dei tipi di luoghi.

Ottieni i dettagli del luogo

Per ottenere i dettagli del luogo selezionato, aggiungi un listener gmp-select a PlaceAutocompleteElement, come mostrato nell'esempio seguente:

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

Vedi l'esempio di codice completo

Nell'esempio precedente, il listener di eventi restituisce un oggetto della classe Place. Chiama il numero place.fetchFields() per ottenere i campi di dati di Place Details necessari per la tua applicazione.

Il listener nell'esempio successivo richiede informazioni sul luogo e le visualizza su una mappa.

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

Vedi l'esempio di codice completo

Mappe di esempio

Questa sezione contiene il codice completo delle mappe di esempio mostrate in questa pagina.

Elemento di completamento automatico

Questo esempio aggiunge un widget di completamento automatico a una pagina web e mostra i risultati per ogni luogo selezionato.

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>

Prova campione

Mappa con completamento automatico

Questo esempio mostra come aggiungere un widget di completamento automatico a una mappa di 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>

Prova campione

Utilizzare il componente Selettore luogo

Il componente di selezione del luogo è un input di testo che consente agli utenti finali di cercare un indirizzo o un luogo specifico utilizzando il completamento automatico. Fa parte della Extended Component Library, un insieme di componenti web che aiutano gli sviluppatori a creare mappe e funzionalità di localizzazione migliori più rapidamente.

Utilizza lo strumento di configurazione del selettore di luoghi per creare codice incorporabile per un componente selettore di luoghi personalizzato, quindi esportalo per utilizzarlo con framework popolari come React e Angular o senza alcun framework.