Crea un servizio di ricerca di attività commerciali nelle vicinanze con Google Maps Platform (JavaScript)
Informazioni su questo codelab
1. Prima di iniziare
Scopri come utilizzare le API Google Maps Platform Maps e Places per creare una ricerca di attività locali, che geolocalizza l'utente e mostra i luoghi interessanti nelle vicinanze. L'app integra la geolocalizzazione, i dettagli dei luoghi, le foto dei luoghi e molto altro.
Prerequisiti
- Conoscenza di base di HTML, CSS e JavaScript
- Un progetto con un account di fatturazione (segui le istruzioni nel passaggio successivo se non hai questo account).
- Per il passaggio di attivazione qui sotto, dovrai attivare l'API Maps JavaScript e l'API Places.
- Una chiave API per il progetto sopra indicato.
Inizia a utilizzare Google Maps Platform
Se non hai mai utilizzato Google Maps Platform, segui la guida introduttiva a Google Maps Platform o guarda la playlist Introduzione a Google Maps Platform per completare la seguente procedura:
- Crea un account di fatturazione.
- Crea un progetto.
- Abilita le API e gli SDK di Google Maps Platform (elencati nella sezione precedente).
- Genera una chiave API.
Attività previste
- Creare una pagina web che mostri una mappa di Google Maps
- Centrato la mappa sulla posizione dell'utente
- Trova luoghi nelle vicinanze e visualizza i risultati come indicatori cliccabili
- Recupera e mostra ulteriori dettagli su ciascun luogo
Che cosa ti serve
- Un browser web, ad esempio Google Chrome (consigliato), Firefox, Safari o Internet Explorer
- Il tuo editor di testo o codice preferito
Genera il codice di esempio
- 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 questa operazione non funziona, fai clic sul pulsante seguente per scaricare tutto il codice di questo codelab, quindi decomprimi il file:
- Passa alla directory che hai appena clonato o scaricato.
cd google-maps-nearby-search-js
Le cartelle stepN
contengono lo stato finale desiderato di ogni passaggio di questo codelab. Sono disponibili come riferimento. Esegui tutte le operazioni di programmazione nella directory denominata work
.
2. Creare una mappa con un centro predefinito
Per creare una mappa Google sulla tua pagina web sono necessari tre passaggi:
- Creare una pagina HTML
- Aggiungere una mappa
- Incolla la tua chiave API
1. Creare una pagina HTML
Di seguito è riportata la mappa creata in questo passaggio. La mappa è centrata sulla Sydney Opera House di Sydney, in Australia. Se l'utente nega l'autorizzazione ad accedere alla propria posizione, la mappa viene mappata in modo predefinito a quella località e fornisce comunque risultati di ricerca interessanti.
- Modifica le directory nella cartella
work/
. In tutti gli altri passaggi del codelab, apporta le modifiche nella versione presente nella cartellawork/
.
cd work
- Nella directory
work/
, utilizza l'editor di testo per creare un file vuoto denominatoindex.html
. - Copia il codice seguente in
index.html
.
indice.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>
- Apri il file
index.html
nel tuo browser web.
open index.html
2. Aggiungere una mappa
Questa sezione illustra come caricare l'API Maps JavaScript nella tua pagina web e scrivere il tuo codice JavaScript che utilizza l'API per aggiungere una mappa alla pagina web.
- Aggiungi questo codice dello script dove vedi
<!-- TODO: Step 1B, Add a map -->
dopo il divmap
e prima del tag</body>
di chiusura.
passaggio1/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 nella chiave API
- Nella riga successiva a
<!-- 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 creata durante i prerequisiti.
passaggio1/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>
- Salva il file HTML su cui stai lavorando.
Prova
Ricarica la visualizzazione del browser del file che stai modificando. Dovresti vedere una mappa ora nel punto in cui il rettangolo grigio si trovava in precedenza. Se viene visualizzato un messaggio di errore, assicurati di aver sostituito "YOUR_API_KEY
" nel tag <script>
finale con la tua chiave API. Vedi sopra per informazioni su come ottenere una chiave API se non ne hai già una.
Codice campione completo
Il codice completo per questo progetto fino a questo momento è disponibile su GitHub.
3. Geolocalizzazione dell'utente
Il passaggio successivo consiste nel visualizzare la posizione geografica dell'utente o del dispositivo in una mappa Google utilizzando la funzionalità Geolocalizzazione HTML5 del browser insieme all'API Maps JavaScript.
Ecco un esempio di mappa che mostra la tua posizione geografica se hai visitato Mountain View, in California:
Che cos'è la geolocalizzazione?
Per geolocalizzazione si intende l'identificazione della posizione geografica di un utente o di un dispositivo informatico tramite una serie di meccanismi di raccolta dati. In genere, la maggior parte dei servizi di geolocalizzazione utilizza indirizzi di rete o dispositivi GPS interni per determinare la posizione. Questa app utilizza la proprietà navigator.geolocation
della geolocalizzazione W3C del browser web per determinare la posizione dell'utente.
Fai una prova
Sostituisci il codice tra i commenti TODO: Step 2, Geolocate your user
e END TODO: Step 2, Geolocate your user
con il seguente codice:
passaggio2/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
- Salva il file.
- Ricarica la pagina.
Ora il browser dovrebbe chiederti l'autorizzazione per condividere la tua posizione con l'app.
- Fai clic una volta su Blocca per vedere se l'errore viene gestito normalmente e rimane centrato su Sydney.
- Ricarica e fai clic su Consenti per verificare se la geolocalizzazione funziona e sposta la mappa nella tua posizione attuale.
Codice campione completo
Il codice completo per questo progetto fino a questo momento è disponibile su GitHub.
4. Ricerca di luoghi nelle vicinanze
Una ricerca nelle vicinanze ti consente di cercare luoghi all'interno di un'area specifica in base alla parola chiave o al 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 la combinazione della proprietà
location
, specificando il centro del cerchio come oggettoLatLng
, 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. Carica 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.
passaggio3/indice.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 richiesta e gestione della risposta Luoghi nelle vicinanze
Dopodiché, scrivi una richiesta PlaceSearch. I campi minimi obbligatori sono:
I campi minimi obbligatori sono:
bounds
, che deve essere un oggettogoogle.maps.LatLngBounds
che definisce l'area di ricerca rettangolare o unlocation
e unradius
; il primo prende un oggettogoogle.maps.LatLng
e il secondo assume un semplice numero intero che rappresenta il raggio in metri. Il raggio massimo consentito è di 50.000 metri. Tieni presente che quandorankBy
è impostato suDISTANCE
, devi specificare una località, ma non puoi specificare un raggio o dei limiti.- Un elemento
keyword
da confrontare con tutti i campi disponibili inclusi, a titolo esemplificativo, nome, tipo e indirizzo, nonché le recensioni dei clienti e altri contenuti di terze parti, oppure un elementotype
, che limita i risultati a posizioni corrispondenti al tipo specificato. È possibile specificare un solo tipo (se viene fornito più di un tipo, vengono ignorati tutti i tipi successivi alla prima voce). Consulta l'elenco dei tipi supportati.
Per questo codelab, utilizzerai la posizione corrente dell'utente come posizione per la ricerca e il ranking dei risultati in base alla distanza.
- Aggiungi quanto segue al commento
TODO: Step 3B1
per scrivere due funzioni: 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
viene fornito nella sezione successiva.
passaggio3/indice.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 */
- Aggiungi questa riga alla fine della funzione
initMap
nel commentoTODO: Step 3B2
.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
- Aggiungi questa riga alla fine della funzione
handleLocationError
nel commentoTODO: Step 3B3
.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);
C. Genera indicatori per i risultati di ricerca
Un indicatore identifica una località su una mappa. Per impostazione predefinita, un indicatore utilizza un'immagine standard. Per informazioni sulla personalizzazione delle immagini indicatori, consulta la sezione Indicatori.
Il costruttore google.maps.Marker
utilizza un singolo valore letterale di oggetto Marker options
, specificando le proprietà iniziali dell'indicatore.
I seguenti campi sono particolarmente importanti e vengono impostati spesso durante la creazione di un indicatore:
- (Obbligatorio)
position
: specifica unLatLng
che identifica la posizione iniziale dell'indicatore. - (Facoltativo)
map
consente di specificare la mappa in cui posizionare l'indicatore. Se non specifichi la mappa al momento della sua creazione, l'indicatore viene creato, ma non viene associato (o visualizzato) sulla mappa. Puoi aggiungere l'indicatore in un secondo momento chiamando il metodosetMap()
dell'indicatore. - Aggiungi il seguente codice dopo il commento
TODO: Step 3C
per impostare la posizione, la mappa e il titolo di un indicatore per luogo restituito nella risposta. Inoltre, puoi utilizzare il metodoextend
della variabilebounds
per assicurarti che il centro e tutti gli indicatori siano visibili sulla mappa.
passaggio3/indice.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
- Salva e ricarica la pagina, quindi fai clic su Consenti per concedere le autorizzazioni di geolocalizzazione.
Dovresti vedere fino a 20 indicatori rossi intorno alla posizione centrale della mappa.
- Ricarica la pagina e questa volta blocca le autorizzazioni di geolocalizzazione.
Ricevi ancora i risultati al centro predefinito della mappa (nell'esempio, il nome predefinito è a Sydney, in Australia)?
Codice campione completo
Il codice completo per questo progetto fino a questo momento è disponibile su GitHub.
5. Mostra dettagli luogo on demand
Una volta che l'ID luogo di un luogo è stato pubblicato (è uno dei campi nei risultati di ricerca nelle vicinanze), puoi richiedere ulteriori dettagli sul luogo, ad esempio indirizzo completo, numero di telefono e valutazioni e recensioni degli utenti. In questo codelab, creerai una barra laterale per visualizzare i dettagli dettagliati dei luoghi e rendere interattivi gli indicatori in modo che l'utente possa selezionare i luoghi per visualizzare i dettagli.
A. Creare una barra laterale generica
Per visualizzare i dettagli del luogo è necessario un posto, quindi ecco un semplice codice di barra laterale che puoi utilizzare per scorrere e visualizzare i dettagli del luogo quando l'utente fa clic su un indicatore.
- Aggiungi il seguente codice al tag
style
dopo il commentoTODO: Step 4A1
:
passaggio4/indice.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;
}
- Nella sezione
body
appena prima dell'elemento div dimap
, aggiungi un elemento 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>
- Nella funzione
initMap()
dopo il commentoTODO: Step 4A3
, inizializza la variabileinfoPane
in questo modo:
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');
B. Aggiungere i listener di clic agli indicatori
- Nella funzione
createMarkers
, aggiungi un listener di clic a ogni indicatore quando li crei.
Il listener di clic recupera i dettagli sul luogo associato a quell'indicatore e chiama la funzione per visualizzare i dettagli.
- Incolla il codice seguente nella funzione
createMarkers
in corrispondenza del commento al codiceTODO: Step 4B
.
Il metodo showDetails
viene implementato nella sezione successiva.
passaggio4/indice.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 unico posto per la richiesta di dettagli, mentre la proprietà fields
è un array di nomi di campi per le informazioni che vuoi che vengano restituite per il luogo. Per un elenco completo dei campi che puoi richiedere, consulta la sezione Interfaccia di PlaceResult.
C. Mostra i dettagli del luogo in una finestra informativa
Una finestra informativa mostra i contenuti (di solito il testo o le immagini) in una finestra di dialogo sopra una determinata posizione su una mappa. La finestra informativa ha un'area di contenuti e uno stelo rastremato. La punta della radice è collegata a una posizione specificata sulla mappa. In genere, le finestre informative sono allegate agli indicatori, ma puoi anche allegare una finestra informativa a una latitudine/longitudine specifica.
- Aggiungi il codice seguente al commento
TODO: Step 4C
per creare unInfoWindow
che mostri il nome e la valutazione dell'attività e la alleghi all'indicatore.
Definisci showPanel
nella sezione successiva per visualizzare i dettagli in una barra laterale.
passaggio4/indice.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 completare un altro div. In questo esempio, utilizza infoPane
che è un nome di variabile arbitraria per l'elemento div con ID "panel
".
- Aggiungi il seguente codice dopo il commento
TODO: Step 4D
.
passaggio4/indice.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. Visualizzazione di una foto del luogo con i dettagli del luogo
Il risultato per getDetails
restituisce un array di massimo 10 foto associate a placeId
. Qui, viene visualizzata la prima foto sopra il nome del luogo nella barra laterale.
- Inserisci questo codice prima della creazione dell'elemento
name
se vuoi che la foto venga visualizzata nella parte superiore della barra laterale.
passaggio4/indice.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
- Salva e ricarica la pagina nel browser e consenti le autorizzazioni di geolocalizzazione.
- Fai clic su un indicatore per visualizzare la finestra popup dall'indicatore con alcuni dettagli e la barra laterale che scompare da sinistra per visualizzare ulteriori dettagli.
- Verifica se la ricerca funziona anche se ricarichi e neghi le autorizzazioni di geolocalizzazione. Modifica la tua parola chiave per una query diversa ed esplora il risultato restituito per quella ricerca.
Codice campione completo
Il codice completo per questo progetto fino a questo momento è disponibile su GitHub.
6. Complimenti
Complimenti! Hai utilizzato molte funzionalità dell'API Maps JavaScript, tra cui la libreria Places
.
Cosa abbiamo trattato
- Creazione di una mappa con la classe google.maps.Map
- Utilizzo del browser dell'utente per la geolocalizzazione e visualizzazione dei risultati su una mappa.
- Aggiungere indicatori alla mappa e rispondere agli eventi relativi ai clic degli utenti.
- Aggiunta di finestre informative per visualizzare ulteriori informazioni quando un utente fa clic su un indicatore.
- Caricamento della Raccolta di luoghi ed esecuzione di una Ricerca nelle vicinanze
- Recupero e visualizzazione dei dettagli dei luoghi e delle foto dei luoghi
Scopri di più
Per ulteriori informazioni sulle mappe, consulta la documentazione dell'API Maps JavaScript e la documentazione della libreria Places, entrambe contenenti guide, tutorial, riferimenti all'API, altri esempi di codice e canali di assistenza. Alcune tra le più note sono Importazione dei dati in Maps, Inizia a tracciare la mappa e l'aggiunta del servizio Street View.
Che tipo di codelab vorresti che creassi dopo?
Il codelab non vuoi vedere sopra? Richiedilo qui con un nuovo problema.