Crea un servizio di ricerca di attività nelle vicinanze con Google Maps Platform (JavaScript)

1. Prima di iniziare

Scopri come utilizzare le API Maps e Places di Google Maps Platform per creare una ricerca di attività locali che geolocalizza l'utente e mostra i luoghi interessanti nelle vicinanze. L'app integra la geolocalizzazione, Place Details, Place Photos e altro ancora.

Prerequisiti

  • Conoscenza di base di HTML, CSS e JavaScript
  • Un progetto con un account di fatturazione (segui le istruzioni del passaggio successivo se non ne hai uno).
  • Per il passaggio di attivazione riportato di seguito, devi abilitare l'API Maps JavaScript e l'API Places.
  • Una chiave API per il progetto precedente.

Inizia a utilizzare Google Maps Platform

Se non hai mai utilizzato Google Maps Platform, segui la guida Inizia a utilizzare Google Maps Platform o guarda la playlist Inizia a utilizzare Google Maps Platform per completare i seguenti passaggi:

  1. Crea un account di fatturazione.
  2. Creare un progetto.
  3. Abilita le API e gli SDK di Google Maps Platform (elencati nella sezione precedente).
  4. Genera una chiave API.

Attività previste

  • Creare una pagina web che mostri una mappa di Google
  • La mappa è centrata sulla posizione dell'utente
  • Trova luoghi nelle vicinanze e visualizza i risultati come indicatori selezionabili
  • Recuperare e mostrare maggiori dettagli su ogni luogo

ae1caf211daa484d.png

Che cosa ti serve

  • Un browser web, ad esempio Google Chrome (consigliato), Firefox, Safari o Internet Explorer
  • Il tuo editor di testo o di codice preferito

Recupera il codice campione

  1. Apri l'interfaccia a riga di comando (Terminale su macOS o Prompt dei comandi su Windows) e scarica il codice di esempio con questo comando:
git clone https://github.com/googlecodelabs/google-maps-nearby-search-js/

Se non funziona, fai clic sul pulsante seguente per scaricare tutto il codice di questo codelab, quindi decomprimi il file:

Scarica il codice

  1. Passa alla directory appena clonata o scaricata.
cd google-maps-nearby-search-js

Le cartelle stepN contengono lo stato finale desiderato di ogni passaggio di questo codelab. Sono presenti a scopo di riferimento. Esegui tutto il lavoro di codifica nella directory denominata work.

2. Crea una mappa con un centro predefinito

Per creare una mappa di Google sulla tua pagina web, segui questi tre passaggi:

  1. Creare una pagina HTML
  2. Aggiungere una mappa
  3. Incolla la chiave API

1. Creare una pagina HTML

Di seguito è riportata la mappa creata in questo passaggio. La mappa è centrata sulla Sydney Opera House a Sydney, in Australia. Se l'utente nega l'autorizzazione per ottenere la sua posizione, la mappa viene impostata su questa posizione e fornisce comunque risultati di ricerca interessanti.

569b9781658fec74.png

  1. Passa alla directory della cartella work/. Nella parte restante del codelab, apporta le modifiche alla versione nella cartella work/.
cd work
  1. Nella directory work/, utilizza l'editor di testo per creare un file vuoto denominato index.html.
  2. Copia il seguente codice in index.html.

index.html

<!DOCTYPE html>
<html>

<head>
  <title>Sushi Finder</title>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <style>
    /* Always set the map height explicitly to define the size of the div
     * element that contains the map. */
    #map {
      height: 100%;
      background-color: grey;
    }

    /* Optional: Makes the sample page fill the window. */
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }

    /* TODO: Step 4A1: Make a generic sidebar. */
  </style>
</head>

<body>
  <!-- TODO: Step 4A2: Add a generic sidebar -->

  <!-- Map appears here -->
  <div id="map"></div>

  <!-- TODO: Step 1B, Add a map -->
</body>

</html>
  1. Apri il file index.html nel browser web.
open index.html

2. Aggiungere una mappa

Questa sezione mostra come caricare l'API Maps JavaScript nella tua pagina web e scrivere il tuo JavaScript che utilizza l'API per aggiungere una mappa alla pagina web.

  1. Aggiungi questo codice dello script dove vedi <!-- TODO: Step 1B, Add a map --> dopo il div map e prima del tag di chiusura </body>.

step1/index.html

<!-- TODO: Step 1B, Add a map -->
<script>
    /* Note: This example requires that you consent to location sharing when
     * prompted by your browser. If you see the error "Geolocation permission
     * denied.", it means you probably did not give permission for the browser * to locate you. */

    /* TODO: Step 2, Geolocate your user
     * Replace the code from here to the END TODO comment with new code from
     * codelab instructions. */
    let pos;
    let map;
    function initMap() {
        // Set the default location and initialize all variables
        pos = {lat: -33.857, lng: 151.213};
        map = new google.maps.Map(document.getElementById('map'), {
            center: pos,
            zoom: 15
        });
    }
    /* END TODO: Step 2, Geolocate your user */
</script>

<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

3. Incolla la chiave API

  1. Nella riga dopo <!-- TODO: Step 1C, Get an API key -->, copia e sostituisci il valore del parametro chiave nell'URL di origine dello script con la chiave API che hai creato durante i prerequisiti.

step1/index.html

<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
  1. Salva il file HTML su cui stai lavorando.

Prova

Ricarica la visualizzazione del browser del file che hai modificato. Ora dovresti vedere una mappa al posto del rettangolo grigio. Se invece visualizzi un messaggio di errore, assicurati di aver sostituito "YOUR_API_KEY" nel tag <script> finale con la tua chiave API. Consulta la sezione precedente per scoprire come ottenere una chiave API se non ne hai già una.

Codice di esempio completo

Il codice completo di questo progetto fino a questo punto è disponibile su GitHub.

3. Geolocalizzare l'utente

Successivamente, devi visualizzare la posizione geografica dell'utente o del dispositivo su una mappa Google utilizzando la funzionalità di geolocalizzazione HTML5 del browser insieme all'API Maps JavaScript.

Ecco un esempio di mappa che mostra la tua posizione geografica se stai navigando da Mountain View, in California:

1dbb3fec117cd895.png

Che cos'è la geolocalizzazione?

La geolocalizzazione si riferisce all'identificazione della posizione geografica di un utente o di un dispositivo informatico tramite una serie di meccanismi di raccolta dei dati. In genere, la maggior parte dei servizi di geolocalizzazione utilizza indirizzi di routing di rete o dispositivi GPS interni per determinare questa posizione. Questa app utilizza la proprietà navigator.geolocation dello standard W3C Geolocation del browser web per determinare la posizione dell'utente.

Prova anche tu

Sostituisci il codice tra i commenti TODO: Step 2, Geolocate your user e END TODO: Step 2, Geolocate your user con il seguente codice:

step2/index.html

/* TODO: Step 2, Geolocate your user
    * Replace the code from here to the END TODO comment with this code
    * from codelab instructions. */
let pos;
let map;
let bounds;
let infoWindow;
let currentInfoWindow;
let service;
let infoPane;
function initMap() {
    // Initialize variables
    bounds = new google.maps.LatLngBounds();
    infoWindow = new google.maps.InfoWindow;
    currentInfoWindow = infoWindow;
    /* TODO: Step 4A3: Add a generic sidebar */

    // Try HTML5 geolocation
    if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(position => {
        pos = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
        };
        map = new google.maps.Map(document.getElementById('map'), {
        center: pos,
        zoom: 15
        });
        bounds.extend(pos);

        infoWindow.setPosition(pos);
        infoWindow.setContent('Location found.');
        infoWindow.open(map);
        map.setCenter(pos);

        /* TODO: Step 3B2, Call the Places Nearby Search */
    }, () => {
        // Browser supports geolocation, but user has denied permission
        handleLocationError(true, infoWindow);
    });
    } else {
    // Browser doesn't support geolocation
    handleLocationError(false, infoWindow);
    }
}

// Handle a geolocation error
function handleLocationError(browserHasGeolocation, infoWindow) {
    // Set default location to Sydney, Australia
    pos = {lat: -33.856, lng: 151.215};
    map = new google.maps.Map(document.getElementById('map'), {
    center: pos,
    zoom: 15
    });

    // Display an InfoWindow at the map center
    infoWindow.setPosition(pos);
    infoWindow.setContent(browserHasGeolocation ?
    'Geolocation permissions denied. Using default location.' :
    'Error: Your browser doesn\'t support geolocation.');
    infoWindow.open(map);
    currentInfoWindow = infoWindow;

    /* TODO: Step 3B3, Call the Places Nearby Search */
}
/* END TODO: Step 2, Geolocate your user */
/* TODO: Step 3B1, Call the Places Nearby Search */

Prova

  1. Salva il file.
  2. Ricarica la pagina.

Il browser dovrebbe ora chiederti l'autorizzazione per condividere la tua posizione con l'app.

  1. Fai clic su Blocca una volta per verificare se l'errore viene gestito correttamente e se la mappa rimane centrata su Sydney.
  2. Ricarica di nuovo e fai clic su Consenti per verificare se la geolocalizzazione funziona e sposta la mappa sulla tua posizione attuale.

Codice di esempio completo

Il codice completo di questo progetto fino a questo punto è disponibile su GitHub.

4. Luoghi nelle vicinanze

Una ricerca nelle vicinanze ti consente di cercare luoghi all'interno di un'area specifica per parola chiave o tipo. Una ricerca nelle vicinanze deve sempre includere una località, che può essere specificata in uno dei due modi seguenti:

  • Un oggetto LatLngBounds che definisce un'area di ricerca rettangolare
  • Un'area circolare definita come combinazione della proprietà location, che specifica il centro del cerchio come oggetto LatLng, e un raggio, misurato in metri

Avvia una ricerca nelle vicinanze con una chiamata al metodo PlacesService nearbySearch(), che restituirà un array di oggetti PlaceResult.

A. Caricare la libreria Places

Innanzitutto, per accedere ai servizi della libreria Places, aggiorna l'URL di origine dello script per introdurre il parametro libraries e aggiungi places come valore.

step3/index.html

<!-- TODO: Step 3A, Load the Places Library -->
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">

B. Chiama la richiesta di ricerca di luoghi nelle vicinanze e gestisci la risposta

A questo punto, crea una richiesta PlaceSearch. I campi minimi obbligatori sono:

I campi minimi obbligatori sono:

  • bounds, che deve essere un oggetto google.maps.LatLngBounds che definisce l'area di ricerca rettangolare, o un location e un radius; il primo accetta un oggetto google.maps.LatLng, mentre il secondo accetta un semplice numero intero che rappresenta il raggio del cerchio in metri. Il raggio massimo consentito è 50.000 metri. Tieni presente che quando rankBy è impostato su DISTANCE, devi specificare una località, ma non puoi specificare un raggio o dei limiti.
  • Un keyword da confrontare con tutti i campi disponibili, inclusi, a titolo esemplificativo, nome, tipo e indirizzo, nonché recensioni dei clienti e altri contenuti di terze parti, o un type, che limita i risultati ai luoghi che corrispondono al tipo specificato. È possibile specificare un solo tipo (se ne vengono forniti più di uno, tutti i tipi successivi alla prima voce vengono ignorati). Consulta l'elenco dei tipi supportati.

Per questo codelab, utilizzerai la posizione attuale dell'utente come posizione per la ricerca e classificherai i risultati in base alla distanza.

  1. Aggiungi quanto segue al commento TODO: Step 3B1 per scrivere due funzioni per chiamare la ricerca e gestire la risposta.

La parola chiave sushi viene utilizzata come termine di ricerca, ma puoi modificarla. Il codice per definire la funzione createMarkers è fornito nella sezione successiva.

step3/index.html

/* TODO: Step 3B1, Call the Places Nearby Search */
// Perform a Places Nearby Search Request
function getNearbyPlaces(position) {
    let request = {
    location: position,
    rankBy: google.maps.places.RankBy.DISTANCE,
    keyword: 'sushi'
    };

    service = new google.maps.places.PlacesService(map);
    service.nearbySearch(request, nearbyCallback);
}

// Handle the results (up to 20) of the Nearby Search
function nearbyCallback(results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
    createMarkers(results);
    }
}

/* TODO: Step 3C, Generate markers for search results */
  1. Aggiungi questa riga alla fine della funzione initMap nel commento TODO: Step 3B2.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
  1. Aggiungi questa riga alla fine della funzione handleLocationError nel commento TODO: Step 3B3.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);

C. Generare indicatori per i risultati di ricerca

Un indicatore identifica una posizione su una mappa. Per impostazione predefinita, un indicatore utilizza un'immagine standard. Per informazioni sulla personalizzazione delle immagini dei marcatori, vedi Marcatori.

Il costruttore google.maps.Marker accetta un singolo valore letterale dell'oggetto Marker options, che specifica le proprietà iniziali del marcatore.

I seguenti campi sono particolarmente importanti e vengono impostati comunemente durante la creazione di un indicatore:

  • position (obbligatorio) specifica un LatLng che identifica la posizione iniziale del marcatore.
  • map (facoltativo) specifica la mappa su cui posizionare l'indicatore. Se non specifichi la mappa durante la costruzione del marcatore, il marcatore viene creato, ma non è collegato (o visualizzato) alla mappa. Puoi aggiungere il marcatore in un secondo momento chiamando il metodo setMap() del marcatore.
  • Aggiungi il seguente codice dopo il commento TODO: Step 3C per impostare la posizione, la mappa e il titolo di un indicatore per ogni luogo restituito nella risposta. Utilizza anche il metodo extend della variabile bounds per assicurarti che il centro e tutti i marcatori siano visibili sulla mappa.

step3/index.html

/* TODO: Step 3C, Generate markers for search results */
// Set markers at the location of each place result
function createMarkers(places) {
    places.forEach(place => {
    let marker = new google.maps.Marker({
        position: place.geometry.location,
        map: map,
        title: place.name
    });

    /* TODO: Step 4B: Add click listeners to the markers */

    // Adjust the map bounds to include the location of this marker
    bounds.extend(place.geometry.location);
    });
    /* Once all the markers have been placed, adjust the bounds of the map to
    * show all the markers within the visible area. */
    map.fitBounds(bounds);
}

/* TODO: Step 4C: Show place details in an info window */

Prova

  1. Salva e ricarica la pagina, quindi fai clic su Consenti per concedere le autorizzazioni di geolocalizzazione.

Dovresti visualizzare fino a 20 indicatori rossi intorno alla posizione centrale della mappa.

  1. Ricarica la pagina e blocca le autorizzazioni di geolocalizzazione.

Ricevi ancora risultati nel centro predefinito della mappa (nell'esempio, il centro predefinito è Sydney, in Australia)?

Codice di esempio completo

Il codice completo di questo progetto fino a questo punto è disponibile su GitHub.

5. Mostrare i dettagli del luogo su richiesta

Una volta ottenuto l'ID luogo di un luogo (fornito come uno dei campi nei risultati della ricerca nelle vicinanze), puoi richiedere ulteriori dettagli sul luogo, come indirizzo completo, numero di telefono e valutazioni e recensioni degli utenti. In questo codelab, creerai una barra laterale per visualizzare i dettagli avanzati dei luoghi e rendere interattivi i marcatori in modo che l'utente possa selezionare i luoghi per visualizzarne i dettagli.

A. Creare una barra laterale generica

Hai bisogno di un posto in cui visualizzare i dettagli del luogo, quindi ecco un semplice codice per una barra laterale che puoi utilizzare per far scorrere e visualizzare i dettagli del luogo quando l'utente fa clic su un indicatore.

  1. Aggiungi il seguente codice al tag style dopo il commento TODO: Step 4A1:

step4/index.html

/* TODO: Step 4A1: Make a generic sidebar */
/* Styling for an info pane that slides out from the left. 
    * Hidden by default. */
#panel {
    height: 100%;
    width: null;
    background-color: white;
    position: fixed;
    z-index: 1;
    overflow-x: hidden;
    transition: all .2s ease-out;
}

.open {
    width: 250px;
}

/* Styling for place details */
.hero {
    width: 100%;
    height: auto;
    max-height: 166px;
    display: block;
}

.place,
p {
    font-family: 'open sans', arial, sans-serif;
    padding-left: 18px;
    padding-right: 18px;
}

.details {
    color: darkslategrey;
}

a {
    text-decoration: none;
    color: cadetblue;
}
  1. Nella sezione body appena prima del div map, aggiungi un div per il riquadro dei dettagli.
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- The slide-out panel for showing place details -->
<div id="panel"></div>
  1. Nella funzione initMap() dopo il commento TODO: Step 4A3, inizializza la variabile infoPane in questo modo:
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');

B. Aggiungere listener di clic ai marker

  1. Nella funzione createMarkers, aggiungi un listener di clic a ogni indicatore man mano che li crei.

Il listener di clic recupera i dettagli del luogo associato al marker e chiama la funzione per visualizzarli.

  1. Incolla il seguente codice all'interno della funzione createMarkers nel commento del codice TODO: Step 4B.

Il metodo showDetails viene implementato nella sezione successiva.

step4/index.html

/* TODO: Step 4B: Add click listeners to the markers */
// Add click listener to each marker
google.maps.event.addListener(marker, 'click', () => {
    let request = {
    placeId: place.place_id,
    fields: ['name', 'formatted_address', 'geometry', 'rating',
        'website', 'photos']
    };

    /* Only fetch the details of a place when the user clicks on a marker.
    * If we fetch the details for all place results as soon as we get
    * the search response, we will hit API rate limits. */
    service.getDetails(request, (placeResult, status) => {
    showDetails(placeResult, marker, status)
    });
});

Nella richiesta addListener, la proprietà placeId specifica un singolo luogo per la richiesta di dettagli e la proprietà fields è un array di nomi di campi per le informazioni che vuoi vengano restituite sul luogo. Per un elenco completo dei campi che puoi richiedere, consulta l'interfaccia PlaceResult.

C. Mostrare i dettagli del luogo in una finestra informativa

Una finestra informativa mostra contenuti (di solito testo o immagini) in una finestra di dialogo sopra una determinata posizione su una mappa. La finestra delle informazioni ha un'area di contenuti e un gambo affusolato. La punta dello stelo è collegata a una posizione specificata sulla mappa. In genere, le finestre informative sono associate ai marcatori, ma puoi anche associarle a una latitudine/longitudine specifica.

  1. Aggiungi il seguente codice al commento TODO: Step 4C per creare un InfoWindow che mostri il nome e la valutazione dell'attività e lo colleghi al marcatore.

Definisci showPanel nella sezione successiva per visualizzare i dettagli in una barra laterale.

step4/index.html

/* TODO: Step 4C: Show place details in an info window */
// Builds an InfoWindow to display details above the marker
function showDetails(placeResult, marker, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
    let placeInfowindow = new google.maps.InfoWindow();
    placeInfowindow.setContent('<div><strong>' + placeResult.name +
        '</strong><br>' + 'Rating: ' + placeResult.rating + '</div>');
    placeInfowindow.open(marker.map, marker);
    currentInfoWindow.close();
    currentInfoWindow = placeInfowindow;
    showPanel(placeResult);
    } else {
    console.log('showDetails failed: ' + status);
    }
}

/* TODO: Step 4D: Load place details in a sidebar */

D. Caricare i dettagli del luogo in una barra laterale

Utilizza gli stessi dettagli restituiti nell'oggetto PlaceResult per compilare un altro div. In questo esempio, utilizza infoPane, che è un nome di variabile arbitrario per il div con l'ID "panel". Ogni volta che l'utente fa clic su un nuovo indicatore, questo codice chiude la barra laterale se era già aperta, cancella i vecchi dettagli, aggiunge i nuovi dettagli e apre la barra laterale.

  1. Aggiungi il codice seguente dopo il commento TODO: Step 4D.

step4/index.html

/* TODO: Step 4D: Load place details in a sidebar */
// Displays place details in a sidebar
function showPanel(placeResult) {
    // If infoPane is already open, close it
    if (infoPane.classList.contains("open")) {
    infoPane.classList.remove("open");
    }

    // Clear the previous details
    while (infoPane.lastChild) {
    infoPane.removeChild(infoPane.lastChild);
    }

    /* TODO: Step 4E: Display a Place Photo with the Place Details */

    // Add place details with text formatting
    let name = document.createElement('h1');
    name.classList.add('place');
    name.textContent = placeResult.name;
    infoPane.appendChild(name);
    if (placeResult.rating != null) {
    let rating = document.createElement('p');
    rating.classList.add('details');
    rating.textContent = `Rating: ${placeResult.rating} \u272e`;
    infoPane.appendChild(rating);
    }
    let address = document.createElement('p');
    address.classList.add('details');
    address.textContent = placeResult.formatted_address;
    infoPane.appendChild(address);
    if (placeResult.website) {
    let websitePara = document.createElement('p');
    let websiteLink = document.createElement('a');
    let websiteUrl = document.createTextNode(placeResult.website);
    websiteLink.appendChild(websiteUrl);
    websiteLink.title = placeResult.website;
    websiteLink.href = placeResult.website;
    websitePara.appendChild(websiteLink);
    infoPane.appendChild(websitePara);
    }

    // Open the infoPane
    infoPane.classList.add("open");
}

E. Visualizzare una foto del luogo con i dettagli del luogo

Il risultato getDetails restituisce un array di massimo 10 foto associate a placeId. Qui, la prima foto viene visualizzata sopra il nome del luogo nella barra laterale.

  1. Inserisci questo codice prima della creazione dell'elemento name se vuoi che la foto venga visualizzata nella parte superiore della barra laterale.

step4/index.html

/* TODO: Step 4E: Display a Place Photo with the Place Details */
// Add the primary photo, if there is one
if (placeResult.photos != null) {
    let firstPhoto = placeResult.photos[0];
    let photo = document.createElement('img');
    photo.classList.add('hero');
    photo.src = firstPhoto.getUrl();
    infoPane.appendChild(photo);
}

Prova

  1. Salva e ricarica la pagina nel browser e consenti le autorizzazioni di geolocalizzazione.
  2. Fai clic su un indicatore per visualizzare la finestra informativa che si apre dall'indicatore e mostra alcuni dettagli, mentre la barra laterale si apre da sinistra per mostrare altri dettagli.
  3. Verifica se la ricerca funziona anche se ricarichi la pagina e neghi le autorizzazioni di geolocalizzazione. Modifica la parola chiave di ricerca per una query diversa ed esplora il risultato restituito per quella ricerca.

ae1caf211daa484d.png

Codice di esempio completo

Il codice completo di questo progetto fino a questo punto è disponibile su GitHub.

6. Complimenti

Complimenti! Hai utilizzato molte funzionalità dell'API Maps JavaScript, inclusa la libreria Places.

Argomenti trattati

Scopri di più

Per fare ancora di più con le mappe, esplora la documentazione dell'API Maps JavaScript e la documentazione della libreria Places, che contengono guide, tutorial, il riferimento API, altri esempi di codice e canali di assistenza. Alcune funzionalità popolari sono Importazione di dati in Maps, Inizia a personalizzare la mappa e l'aggiunta del servizio Street View.

Quale tipo di codelab vorresti che creassimo per primo?

Altri esempi di utilizzo di informazioni avanzate sui luoghi Altri codelab che utilizzano l'API Maps Platform JavaScript Altri codelab per Android Altri codelab per iOS Visualizzazione di dati basati sulla posizione sulle mappe Stili personalizzati delle mappe Utilizzo di Street View

Il codelab che ti interessa non è elencato sopra? Richiedilo con un nuovo problema qui.