1. Avant de commencer
Découvrez comment utiliser les API Maps et Places de Google Maps Platform pour créer une recherche d'entreprises locales qui géolocalise l'utilisateur et affiche les lieux intéressants à proximité. L'application intègre la géolocalisation, Place Details, Place Photos et plus encore.
Prérequis
- Connaissances de base en HTML, CSS et JavaScript
- Un projet avec un compte de facturation (suivez les instructions de l'étape suivante si vous n'en avez pas).
- Pour réaliser l'étape ci-dessous, vous devez activer l'API Maps JavaScript et l'API Places.
- Clé API pour le projet ci-dessus.
Premiers pas avec Google Maps Platform
Si vous n'avez jamais utilisé Google Maps Platform, suivez le guide Premiers pas avec Google Maps Platform ou regardez la playlist de démarrage avec Google Maps Platform pour effectuer les étapes suivantes :
- Créer un compte de facturation
- Créer un projet
- Activer les SDK et les API Google Maps Platform (répertoriés dans la section précédente)
- Générer une clé API
Objectifs de l'atelier
- Créer une page Web qui affiche une carte Google
- La carte a été centrée sur la position de l'utilisateur.
- Trouver des lieux à proximité et afficher les résultats sous forme de repères cliquables
- Récupérer et afficher plus d'informations sur chaque lieu
Prérequis
- Un navigateur Web, tel que Google Chrome (recommandé), Firefox, Safari ou Internet Explorer
- Votre éditeur de texte ou de code préféré
Obtenir l'exemple de code
- Ouvrez votre interface de ligne de commande (Terminal sur macOS ou Invite de commandes sur Windows) et téléchargez l'exemple de code avec cette commande :
git clone https://github.com/googlecodelabs/google-maps-nearby-search-js/
Si cela ne fonctionne pas, cliquez sur le bouton suivant pour télécharger l'ensemble du code de cet atelier de programmation, puis décompressez le fichier :
- Accédez au répertoire que vous venez de cloner ou de télécharger.
cd google-maps-nearby-search-js
Les dossiers stepN
contiennent l'état final souhaité de chaque étape de cet atelier de programmation. Ils sont fournis à titre de référence. Effectuez tout votre travail de codage dans le répertoire work
.
2. Créer une carte avec un centre par défaut
Pour créer une carte Google sur votre page Web, trois étapes sont nécessaires :
- Créer une page HTML
- Ajouter une carte
- Collez votre clé API.
1. Créer une page HTML
Vous trouverez ci-dessous la carte créée à cette étape. La carte est centrée sur l'opéra de Sydney, en Australie. Si l'utilisateur refuse l'autorisation d'accéder à sa position, la carte est définie par défaut sur cette position et fournit toujours des résultats de recherche intéressants.
- Remplacez les répertoires par votre dossier
work/
. Dans la suite de cet atelier de programmation, apportez vos modifications à la version du dossierwork/
.
cd work
- Dans le répertoire
work/
, utilisez votre éditeur de texte pour créer un fichier vide nomméindex.html
. - Copiez le code suivant dans
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>
- Ouvrez le fichier
index.html
dans votre navigateur Web.
open index.html
2. Ajouter une carte
Cette section explique comment charger l'API Maps JavaScript sur votre page Web et comment écrire votre propre JavaScript qui utilise l'API pour ajouter une carte à la page Web.
- Ajoutez ce code de script à l'endroit où vous voyez
<!-- TODO: Step 1B, Add a map -->
après la balise divmap
et avant la balise de fermeture</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. Collez votre clé API.
- Sur la ligne après
<!-- TODO: Step 1C, Get an API key -->
, copiez et remplacez la valeur du paramètre "key" dans l'URL source du script par la clé API que vous avez créée lors des prérequis.
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>
- Enregistrez le fichier HTML sur lequel vous avez travaillé.
Tester le code
Actualisez la vue du fichier que vous avez modifié dans votre navigateur. Une carte devrait maintenant s'afficher à la place du rectangle gris. Si un message d'erreur s'affiche, assurez-vous d'avoir remplacé "YOUR_API_KEY
" dans la balise <script>
finale par votre propre clé API. Consultez la section ci-dessus pour savoir comment obtenir une clé API si vous n'en avez pas déjà une.
Exemple de code complet
Le code complet de ce projet jusqu'à présent est disponible sur GitHub.
3. Géolocaliser votre utilisateur
Ensuite, vous devez afficher l'emplacement géographique de l'utilisateur ou de l'appareil sur une carte Google en utilisant la fonctionnalité HTML5 Geolocation de votre navigateur ainsi que l'API Maps JavaScript.
Voici un exemple de carte qui affiche votre position géographique si vous naviguez depuis Mountain View, en Californie :
Qu'est-ce que la géolocalisation ?
La géolocalisation est l'identification de l'emplacement géographique d'un utilisateur ou d'un appareil informatique par le biais de divers mécanismes de collecte de données. La plupart des services de géolocalisation s'appuient sur des adresses d'acheminement réseau ou des appareils GPS internes pour déterminer cette position. Cette application utilise la propriété navigator.geolocation
de la norme de géolocalisation W3C du navigateur Web pour déterminer la position de l'utilisateur.
À votre tour !
Remplacez le code entre les commentaires TODO: Step 2, Geolocate your user
et END TODO: Step 2, Geolocate your user
par le code suivant :
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 */
Tester le code
- Enregistrez votre fichier.
- Actualisez la page.
Votre navigateur devrait maintenant vous demander l'autorisation de partager votre position avec l'application.
- Cliquez une fois sur Bloquer pour voir si l'erreur est gérée correctement et si la carte reste centrée sur Sydney.
- Actualisez de nouveau la page, puis cliquez sur Autoriser pour voir si la géolocalisation fonctionne et si la carte se déplace vers votre position actuelle.
Exemple de code complet
Le code complet de ce projet jusqu'à présent est disponible sur GitHub.
4. Rechercher des adresses à proximité
Une requête Nearby Search permet de rechercher des lieux dans une zone définie par mot clé ou par type. Une requête Nearby Search doit toujours inclure un point géographique, qui doit être spécifié en utilisant au choix :
- Objet
LatLngBounds
définissant une zone de recherche rectangulaire - une zone circulaire définie comme la combinaison de la propriété
location
(qui spécifie le centre du cercle en tant qu'objetLatLng
) et un rayon, mesuré en mètres.
Lancez une recherche Nearby Search en appelant la méthode nearbySearch()
PlacesService
, qui renvoie un tableau d'objets PlaceResult
.
A. Charger la bibliothèque Places
Tout d'abord, pour accéder aux services de la bibliothèque Places, mettez à jour l'URL source de votre script afin d'introduire le paramètre libraries
et d'ajouter places
comme valeur.
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. Appeler la requête Places Nearby Search et gérer la réponse
Ensuite, créez une requête PlaceSearch. Les champs obligatoires sont les suivants :
Les champs obligatoires sont les suivants :
bounds
, qui doit être un objetgoogle.maps.LatLngBounds
définissant la zone de recherche rectangulaire, ou unlocation
et unradius
. La première utilise un objetgoogle.maps.LatLng
et la seconde un entier simple représentant le rayon du cercle en mètres. Le rayon maximum autorisé est de 50 000 mètres. Notez que lorsquerankBy
est défini surDISTANCE
, vous devez spécifier un lieu, mais vous ne pouvez pas spécifier de rayon ni de limites.- Un
keyword
à mettre en correspondance avec tous les champs disponibles, y compris, mais sans s'y limiter, le nom, le type et l'adresse, ainsi que les avis des clients et d'autres contenus tiers, ou untype
, qui limite les résultats aux lieux correspondant au type spécifié. Un seul type peut être spécifié (si plusieurs types sont fournis, tous les types spécifiés après la première entrée sont ignorés). Consultez la liste des types acceptés.
Pour cet atelier de programmation, vous allez utiliser la position actuelle de l'utilisateur comme lieu de recherche et classer les résultats par distance.
- Ajoutez ce qui suit au commentaire
TODO: Step 3B1
pour écrire deux fonctions permettant d'appeler la recherche et de gérer la réponse.
Le mot clé sushi
est utilisé comme terme de recherche, mais vous pouvez le modifier. Le code permettant de définir la fonction createMarkers
est fourni dans la section suivante.
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 */
- Ajoutez cette ligne à la fin de la fonction
initMap
au niveau du commentaireTODO: Step 3B2
.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
- Ajoutez cette ligne à la fin de la fonction
handleLocationError
au niveau du commentaireTODO: Step 3B3
.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);
C. Générer des repères pour les résultats de recherche
Un repère identifie un lieu sur une carte. Par défaut, les marqueurs utilisent des images standard. Pour en savoir plus sur la personnalisation des images de repères, consultez Repères.
Le constructeur google.maps.Marker
n'accepte qu'un littéral d'objet Marker options
, qui spécifie les propriétés initiales du repère.
Les champs suivants sont particulièrement importants et généralement définis lors de la construction d'un marqueur :
position
(obligatoire) spécifie unLatLng
qui identifie l'emplacement initial du repère.map
(facultatif) spécifie la carte sur laquelle placer le repère. Si vous ne spécifiez pas la carte lors de la construction du repère, ce dernier est créé, mais n'est pas associé à (ni affiché sur) la carte. Vous pouvez ajouter le repère ultérieurement en appelant la méthodesetMap()
du repère.- Ajoutez le code suivant après le commentaire
TODO: Step 3C
pour définir la position, la carte et le titre d'un repère par lieu renvoyé dans la réponse. Vous utilisez également la méthodeextend
de la variablebounds
pour vous assurer que le centre et tous les repères sont visibles sur la carte.
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 */
Tester le code
- Enregistrez et actualisez la page, puis cliquez sur Autoriser pour accorder les autorisations de géolocalisation.
Vous devriez voir jusqu'à 20 repères rouges autour du centre de la carte.
- Actualisez à nouveau la page et bloquez cette fois les autorisations de géolocalisation.
Obtenez-vous toujours des résultats au centre par défaut de votre carte (dans l'exemple, le centre par défaut se trouve à Sydney, en Australie) ?
Exemple de code complet
Le code complet de ce projet jusqu'à présent est disponible sur GitHub.
5. Afficher les détails de lieux à la demande
Une fois que vous avez obtenu l'ID d'un lieu (fourni dans l'un des champs des résultats de votre recherche à proximité), vous pouvez demander des informations supplémentaires sur ce lieu, comme son adresse complète, son numéro de téléphone, ainsi que les notes et avis des utilisateurs. Dans cet atelier de programmation, vous allez créer une barre latérale pour afficher des informations détaillées sur les lieux et rendre les repères interactifs afin que l'utilisateur puisse sélectionner des lieux pour afficher des informations.
A. Créer une barre latérale générique
Vous avez besoin d'un emplacement pour afficher les détails du lieu. Voici donc un code simple pour une barre latérale que vous pouvez utiliser pour afficher les détails du lieu lorsque l'utilisateur clique sur un repère.
- Ajoutez le code suivant à la balise
style
après le commentaireTODO: 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;
}
- Dans la section
body
juste avant la divmap
, ajoutez une div pour le panneau d'informations.
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- The slide-out panel for showing place details -->
<div id="panel"></div>
- Dans la fonction
initMap()
, après le commentaireTODO: Step 4A3
, initialisez la variableinfoPane
comme suit :
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');
B. Ajouter des écouteurs de clics aux repères
- Dans la fonction
createMarkers
, ajoutez un écouteur de clics à chaque repère au fur et à mesure de leur création.
L'écouteur de clic récupère les informations sur le lieu associé à ce repère et appelle la fonction pour afficher les détails.
- Collez le code suivant dans la fonction
createMarkers
au niveau du commentaire de codeTODO: Step 4B
.
La méthode showDetails
est implémentée dans la section suivante.
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)
});
});
Dans la requête addListener
, la propriété placeId
spécifie un seul lieu pour la requête d'informations, et la propriété fields
est un tableau de noms de champs pour les informations que vous souhaitez obtenir sur le lieu. Pour obtenir la liste complète des champs que vous pouvez demander, consultez l'interface PlaceResult.
C. Afficher les détails du lieu dans une fenêtre d'informations
Une fenêtre d'informations affiche du contenu (généralement du texte ou des images) dans une boîte de dialogue au-dessus d'un emplacement donné sur une carte. La fenêtre d'info est composée d'une zone de contenu et d'un pied effilé. L'extrémité du pied est reliée à un point géographique spécifié sur la carte. En général, les fenêtres d'informations sont associées à des repères, mais vous pouvez aussi en associer une à une latitude/longitude spécifique.
- Ajoutez le code suivant au niveau du commentaire
TODO: Step 4C
pour créer unInfoWindow
qui affiche le nom et la note de l'établissement, et associez cette fenêtre au repère.
Vous définissez showPanel
dans la section suivante pour afficher les détails dans une barre latérale.
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. Charger les détails d'un lieu dans une barre latérale
Utilisez les mêmes informations renvoyées dans l'objet PlaceResult
pour remplir une autre div. Dans cet exemple, utilisez infoPane
, qui est un nom de variable arbitraire pour la div avec l'ID "panel
". Chaque fois que l'utilisateur clique sur un nouveau repère, ce code ferme la barre latérale si elle était déjà ouverte, efface les anciennes informations, ajoute les nouvelles informations et ouvre la barre latérale.
- Ajoutez le code suivant après le commentaire
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. Afficher une photo de lieu avec les détails du lieu
Le résultat getDetails
renvoie un tableau contenant jusqu'à 10 photos associées à placeId
. Ici, vous affichez la première photo au-dessus du nom du lieu dans la barre latérale.
- Placez ce code avant la création de l'élément
name
si vous souhaitez que la photo apparaisse en haut de la barre latérale.
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);
}
Tester le code
- Enregistrez et actualisez la page dans votre navigateur, puis autorisez la géolocalisation.
- Cliquez sur un repère pour afficher la fenêtre d'informations qui s'affiche à partir du repère et qui contient quelques détails. La barre latérale s'affiche également sur la gauche pour afficher plus de détails.
- Testez si la recherche fonctionne également si vous actualisez la page et refusez les autorisations de géolocalisation. Modifiez votre mot clé de recherche pour une autre requête et explorez le résultat renvoyé pour cette recherche.
Exemple de code complet
Le code complet de ce projet jusqu'à présent est disponible sur GitHub.
6. Félicitations
Félicitations ! Vous avez utilisé de nombreuses fonctionnalités de l'API Maps JavaScript, y compris la bibliothèque Places
.
Points abordés
- Créer une carte avec la classe google.maps.Map
- Utiliser le navigateur de l'utilisateur pour la géolocalisation et afficher les résultats sur une carte
- Ajouter des repères à votre carte et répondre aux événements de clic des utilisateurs sur ces repères
- Ajouter des fenêtres d'informations pour afficher plus de renseignements lorsqu'un utilisateur clique sur un repère
- Chargement de la bibliothèque Places et exécution d'une recherche à proximité
- Récupérer et afficher les détails d'un lieu et les photos d'un lieu
En savoir plus
Pour aller encore plus loin avec les cartes, consultez la documentation de l'API Maps JavaScript et la documentation de la bibliothèque Places. Vous y trouverez des guides, des tutoriels, la référence de l'API, d'autres exemples de code et des canaux d'assistance. Parmi les fonctionnalités les plus populaires, citons l'importation de données dans Maps, le style de carte et l'ajout du service Street View.
Quel type d'atelier de programmation souhaiteriez-vous que nous créions ensuite ?
L'atelier de programmation que vous souhaitez suivre ne figure pas dans la liste ci-dessus ? Demandez-le en décrivant un nouveau problème ici.