Scoprire luoghi con l'elemento di ricerca di luoghi e l'API Maps JavaScript

Obiettivo

Scopri come integrare l'elemento Place Search con Google Maps per aiutare gli utenti a trovare luoghi utilizzando la ricerca nelle vicinanze o la ricerca di testo, migliorando la loro capacità di esplorare i punti di interesse. Utilizza l'elemento compatto Dettagli luogo per fornire maggiori dettagli sui luoghi visualizzati nella tua applicazione.

Che cos'è l'elemento Place Search?

L'elemento di ricerca di luoghi fa parte di Places UI Kit nell'API Maps JavaScript. È un elemento HTML che visualizza i risultati di una ricerca di luoghi direttamente in un formato di elenco all'interno dell'applicazione. Questo elemento semplifica il processo di visualizzazione dei luoghi trovati utilizzando una ricerca nelle vicinanze o una ricerca di testo, fornendo un'esperienza utente senza interruzioni per la scoperta dei luoghi. Quando un utente seleziona un luogo dall'elenco, puoi visualizzarne i dettagli sulla mappa, spesso utilizzando una finestra informativa e l'elemento Dettagli luogo.

Visualizzare la scoperta di luoghi

L'immagine seguente mostra un esempio dell'elemento di ricerca di luoghi in azione. A sinistra viene visualizzato un elenco di ristoranti (l'elemento di ricerca di luoghi). Quando viene selezionato un ristorante, i relativi dettagli vengono visualizzati in una finestra informativa sulla mappa e la mappa si centra sulla sua posizione.

immagine

Casi d'uso per la scoperta di luoghi

L'integrazione dell'elemento di ricerca di luoghi può migliorare varie applicazioni in diversi settori:

  • Viaggi e turismo:consente ai turisti di cercare attrazioni, hotel o tipi specifici di cucina in una zona.
  • Immobili: consente a potenziali acquirenti o affittuari di trovare scuole, supermercati o opzioni di trasporto pubblico nelle vicinanze.
  • Logistica e servizi:aiuta i conducenti a trovare stazioni di ricarica per veicoli elettrici, stazioni di servizio o centri di assistenza specifici.

Flusso di lavoro della soluzione: implementazione di Place Discovery

Questa sezione illustra i passaggi per integrare l'elemento di ricerca di luoghi per scoprire luoghi su una mappa, inclusi snippet di codice per interagire con il Places UI Kit. Vedremo come inizializzare la mappa e implementare le funzionalità di Ricerca nelle vicinanze e Ricerca di testo. Infine, utilizzeremo l'elemento Dettagli luogo per mostrare ulteriori dettagli su un luogo specifico quando si fa clic sul relativo segnaposto sulla mappa.

Prerequisiti

Si consiglia di avere familiarità con la seguente documentazione:

Attiva l'API Maps JavaScript e Places UI Kit sul tuo progetto.

Prima di iniziare, verifica di aver caricato l'API Maps JavaScript e di aver importato le librerie richieste. Questo documento presuppone inoltre una conoscenza pratica dello sviluppo web, inclusi HTML, CSS e JavaScript.

Aggiungere una mappa alla pagina

Il primo passaggio consiste nell'aggiungere una mappa alla pagina. Questa mappa verrà utilizzata per visualizzare i risultati dell'elemento di ricerca di luoghi come segnaposto selezionabili.

Esistono due modi per aggiungere una mappa a una pagina:

  1. Utilizzo di un gmp-map componente web HTML.
  2. Utilizzando JavaScript.

Gli snippet di codice in questa pagina sono stati generati utilizzando una mappa JavaScript.

La mappa può essere centrata su una posizione in cui vuoi che l'utente cerchi, ad esempio un hotel, oppure inizializzata per chiedere la posizione attuale dell'utente per centrare la mappa. Ai fini di questo documento, utilizzeremo una posizione fissa per ancorare la ricerca.

Se visualizzi luoghi nelle vicinanze di una posizione fissa, ad esempio un hotel, posiziona un indicatore sulla mappa per rappresentare questo luogo. Ad esempio:

immagine

La mappa è centrata su San Francisco, con un segnaposto blu che rappresenta il luogo che stiamo cercando nelle vicinanze. Il colore del segnaposto è stato personalizzato utilizzando PinElement. Il controllo Tipo di mappa è stato nascosto dall'interfaccia utente.

Configurare l'elemento Place Search

Ora possiamo configurare HTML e CSS per visualizzare l'elemento di ricerca di luoghi. Per questo esempio, sposteremo l'elemento sul lato sinistro della mappa, ma ti consigliamo di provare layout diversi per adattarli alla tua applicazione.

L'elemento di ricerca di luoghi utilizza un approccio dichiarativo. Anziché configurarlo interamente in JavaScript, definisci il tipo di ricerca direttamente nel codice HTML incorporando un elemento di richiesta, ad esempio <gmp-place-nearby-search-request>, all'interno del componente <gmp-place-search> principale.

All'interno del codice HTML, inizializza un elemento <gmp-place-search>. Utilizza l'attributo selectable per attivare gli eventi di clic sui risultati. Al suo interno, aggiungi un <gmp-place-nearby-search-request> per specificare che questo elemento verrà utilizzato per la ricerca nelle vicinanze.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Per eseguire una ricerca iniziale e visualizzare i risultati, utilizzeremo JavaScript per ottenere un riferimento all'elemento di richiesta nidificato e impostarne le proprietà. Inizializza un cerchio da utilizzare come locationRestriction, utilizzando la posizione del marcatore del passaggio precedente come punto centrale. Poi, imposta le proprietà locationRestriction e includedPrimaryTypes nell'elemento della richiesta per attivare la ricerca.

Lo snippet di codice è il seguente:

// Get references to the Place Search and its nested request element
const placeSearchElement = document.querySelector("gmp-place-search");
const placeSearchRequestElement = document.querySelector("gmp-place-nearby-search-request");

// Define the location restriction for the search
const circleRestriction = new Circle({
    center: marker.position,
    radius: 500
});

// Set the properties on the request element to perform an initial search for restaurants.
placeSearchRequestElement.locationRestriction = circleRestriction;
placeSearchRequestElement.includedPrimaryTypes = ['restaurant'];

Un esempio di come potrebbe apparire l'applicazione in questa fase è il seguente:

immagine

L'elemento Place Search consente due opzioni di ricerca:

Si tratta di elementi nidificati all'interno di <gmp-place-search>. Quindi, attivi le ricerche impostando le proprietà dell'elemento di richiesta nidificato utilizzando JavaScript.

Questa sezione descrive l'implementazione di entrambi i metodi.

immagine

Per consentire agli utenti di eseguire una ricerca nelle vicinanze, devi prima creare un elemento UI per consentire loro di selezionare un Tipo di luogo. Scegli il metodo di selezione più adatto alla tua applicazione, ad esempio un elenco a discesa compilato con una selezione di tipi di luoghi.

Ti consigliamo di scegliere un sottoinsieme di tipi pertinenti al tuo caso d'uso. Ad esempio, se stai sviluppando un'applicazione per mostrare ai turisti cosa c'è nelle vicinanze di un hotel, potresti scegliere: bakery, coffee_shop, museum, restaurant e tourist_attraction.

Il codice HTML deve contenere l'elemento <gmp-place-search> con un <gmp-place-nearby-search-request> nidificato all'interno.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Successivamente, crea un listener JavaScript per l'evento change nel selettore del tipo di luogo. Questo listener chiamerà una funzione che aggiorna le proprietà dell'elemento <gmp-place-nearby-search-request>, che attiva automaticamente una nuova ricerca e aggiorna l'elenco.

// Get a reference to the nested request element
const placeSearchRequestElement = document.querySelector('gmp-place-nearby-search-request');

// Function to update the place search based on the selected type
function updatePlaceList() {
    const selectedType = placeTypeSelect.value;
    if (!selectedType) {
        // If no type is selected, don't perform a search.
        // You could optionally hide the list or clear previous results here.
        placeSearchElement.style.display = 'none';
        return;
    }
    placeSearchElement.style.display = 'block';

    // Set properties on the request element to trigger a new search
    placeSearchRequestElement.locationRestriction = searchCircle;
    placeSearchRequestElement.maxResultCount = 8;
    placeSearchRequestElement.includedPrimaryTypes = [selectedType];
}

Lo stesso searchCircle del passaggio di configurazione viene utilizzato per locationRestriction. La proprietà includedPrimaryTypes è impostata sul valore della selezione dell'utente. È impostato anche un maxResultCount facoltativo per limitare il numero di risultati.

immagine

Per attivare la ricerca di testo, la configurazione HTML deve essere modificata. Invece della richiesta di ricerca nelle vicinanze, nidifichi un elemento <gmp-place-text-search-request>.

<gmp-place-search selectable>
  <gmp-place-text-search-request>
  </gmp-place-text-search-request>
</gmp-place-search>

Aggiungi un input di testo e un pulsante di ricerca alla tua UI. Crea un listener JavaScript per l'evento click del pulsante. Il gestore eventi prenderà l'input dell'utente e aggiornerà le proprietà dell'elemento <gmp-place-text-search-request> per eseguire la ricerca.

// Get a reference to the text search request element
const placeTextSearchRequestElement = document.querySelector('gmp-place-text-search-request');
const textSearchInput = document.getElementById('textSearchInput');
const textSearchButton = document.getElementById('textSearchButton');

textSearchButton.addEventListener('click', performTextSearch);

function performTextSearch() {
    const query = textSearchInput.value.trim();
    if (!query) {
        console.log("Search query is empty.");
        return;
    }
    // Set properties on the request element to trigger a new search
    placeTextSearchRequestElement.textQuery = query;
    placeTextSearchRequestElement.locationBias = map.getBounds();
    placeTextSearchRequestElement.maxResultCount = 8;
}

Qui impostiamo la proprietà textQuery con l'input dell'utente. Forniamo anche un locationBias utilizzando i limiti della mappa corrente, che indica all'API di preferire i risultati all'interno di quell'area senza confinarli rigorosamente. Un maxResultCount facoltativo limita il numero di risultati restituiti.

Visualizzare i segnaposto e i dettagli dei luoghi

Ora l'applicazione può eseguire una ricerca di luoghi e compilare l'elemento. Nel passaggio successivo miglioreremo la sua funzionalità:

  • Visualizzazione di segnaposto sulla mappa per ogni luogo inserito nell'elemento Ricerca luoghi.
  • Consente a un utente di fare clic su un segnaposto o sul luogo all'interno dell'elemento Ricerca luoghi per visualizzare ulteriori dettagli su quel luogo specifico.

Il principio di questo passaggio è lo stesso, indipendentemente dal fatto che l'applicazione utilizzi una ricerca nelle vicinanze o una ricerca di testo.

Innanzitutto, aggiungi una variabile globale al codice JavaScript per memorizzare i segnaposto. In questo modo potrai rimuoverli quando la ricerca cambia e gestire gli eventi di clic.

let markers = {};

Crea una funzione per aggiungere indicatori alla mappa. Questa funzione verrà chiamata ogni volta che vengono caricati nuovi risultati di ricerca. In questo modo:

  • Rimuovi eventuali indicatori di luogo esistenti dalla mappa.
  • Scorri i risultati dell'elemento Ricerca luoghi e aggiungi un indicatore per ciascuno.
  • Regola i limiti della mappa in modo che tutti i nuovi indicatori siano visibili.

Per ascoltare quando sono disponibili i risultati di ricerca, aggiungi un listener di eventi gmp-load all'elemento <gmp-place-search>. Questo evento viene attivato al termine di una ricerca e dopo il rendering dei risultati.

Aggiungeremo l'ascoltatore alla nostra funzione di ricerca (ad es. updatePlaceList) e utilizza l'opzione { once: true } per assicurarti che venga attivato solo per i risultati della ricerca corrente.

// In your search function, after setting the request properties:
placeSearchElement.addEventListener('gmp-load', addMarkers, { once: true });

La funzione addMarkers ha questo aspetto:

async function addMarkers() {
    const { LatLngBounds } = await google.maps.importLibrary("core");
    const bounds = new LatLngBounds();

    if (placeSearchElement.places.length > 0) {
        // Remove existing markers
        for (const m in markers) {
            markers[m].map = null;
        }
        markers = {};

        // Loop through each place from the search results
        // and add a marker for each one.
        for (const place of placeSearchElement.places) {
            const marker = new google.maps.marker.AdvancedMarkerElement({
                map: map,
                position: place.location,
            });

            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;

            // Add a click listener for each marker.
            marker.addListener('gmp-click', (event) => {
                // The main logic for showing details will go here.
            });
        }
        // Position the map to display all markers.
        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    }
}

Una volta completato questo passaggio, l'applicazione avrà il seguente aspetto, con la possibilità di mostrare i marcatori per ogni luogo restituito dall'elemento di ricerca di luoghi:

immagine

Ora che abbiamo i marcatori sulla mappa, l'ultimo passaggio consiste nel gestire gli eventi di clic sui marcatori e sugli elementi per mostrare una finestra informativa con i dettagli del luogo, forniti dall'elemento Dettagli luogo. Per questo esempio, utilizzeremo l'elemento compatto Dettagli luogo.

Aggiungi il codice HTML dell'elemento compatto Dettagli luogo al tuo codice, ad esempio:

<gmp-place-details-compact orientation="vertical" style="display: none;">
    <gmp-place-all-content></gmp-place-all-content>
    <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
</gmp-place-details-compact>

Il style è impostato su display: none e non sarà visibile finché non sarà necessario. gmp-place-all-content viene passato per visualizzare tutti i contenuti degli elementi. Per scegliere i contenuti da visualizzare, consulta la documentazione relativa all'elemento compatto Dettagli luogo.

Crea una variabile globale in JavaScript per contenere un riferimento all'elemento compatto Dettagli luogo e completala nel codice di inizializzazione, ad esempio:

let placeDetailsElement;
...
placeDetailsElement = document.querySelector('gmp-place-details-compact');

All'interno della funzione addMarkers, aggiungi un listener di eventi gmp-click a ogni indicatore e configura l'elemento compatto dei dettagli del luogo per mostrare i dettagli del luogo trasmettendo l'ID luogo dell'indicatore corrente.

Una volta completata questa operazione, si apre una finestra informativa per visualizzare l'elemento compatto dei dettagli del luogo, ancorato al marcatore.

Infine, la mappa viene posizionata nell'area visibile del luogo selezionato, rendendolo visibile.

async function addMarkers() {
          ...
            marker.addListener('gmp-click', (event) => {
                //Set up Place Details Compact Widget
                placeDetailsElement.style.display = "block";
                // Remove any existing place request element
                const existingPlaceRequest = placeDetailsElement.querySelector('gmp-place-details-place-request');
                if (existingPlaceRequest) {
                    existingPlaceRequest.remove();
                }
                // Create and configure the new place request element
                const placeRequestElement = new google.maps.places.PlaceDetailsPlaceRequestElement({ place: place.id });
                // Prepend the new place request element to the main widget
                placeDetailsElement.prepend(placeRequestElement);
                if (infoWindow.isOpen) {
                    infoWindow.close();
                }
                infoWindow.setOptions({
                    content: placeDetailsElement
                });
                infoWindow.open({
                    anchor: marker,
                    map: map
                });
                // Position the map to show the selected place
                placeDetailsElement.addEventListener('gmp-load', () => {
                    map.fitBounds(place.viewport, { top: 500, left: 400 });
                });
            });
          ...
        });
    }
}

Per consentire all'utente di fare clic su un luogo nell'elemento Elenco dei luoghi per visualizzare l'elemento compatto Dettagli luogo, aggiungi quanto segue al codice JavaScript dopo la chiamata a configureFromSearchNearbyRequest.

placeSearchElement.addEventListener("gmp-select", ({ place }) => {
    if (markers[place.id]) {
        markers[place.id].click();
    }
});

Una volta completato questo passaggio, l'applicazione potrà utilizzare una ricerca nelle vicinanze o una ricerca di testo per compilare l'elemento Elenco dei luoghi. I risultati mostreranno dei segnaposto sulla mappa e, se fai clic su un segnaposto o su un luogo nell'elemento Elenco luoghi, verrà visualizzata una finestra informativa con i dettagli del luogo, forniti dall'elemento compatto Dettagli luogo.

L'applicazione avrà il seguente aspetto:

immagine

Conclusione

L'elemento Ricerca luoghi combinato con l'elemento compatto Dettagli luogo offre un modo semplificato per aggiungere funzionalità avanzate di scoperta di luoghi alle tue applicazioni Google Maps Platform.

Prova subito Places UI Kit per consentire ai tuoi utenti di trovare ed esplorare luoghi utilizzando ricerche di testo e nelle vicinanze e visualizzare dettagli ricchi sui luoghi, migliorando la loro interazione con i tuoi casi d'uso di scoperta dei luoghi.

Collaboratori

Henrik Valve | DevX Engineer