V1V2
Blog & Projects

Tutoriel sur l'API Google Maps avec la géolocalisation HTML5

Map

Ce tutoriel vient en complément au Tutoriel de géolocalisation en HTML5, et vous apprendra à exploiter les informations de géolocalisation que vous y avez obtenu sur une carte Google Maps. Nous allons réaliser une application qui affiche votre position sur une carte et trace votre parcours en suivant vos déplacements.

L'API Google Maps

Tout d'abord, il est essentiel de bien comprendre ce qu'est une API. Toute application web peut choisir d'autoriser des développeurs tiers à utiliser une partie de ses fonctionnalités. Ces fonctionnalités peuvent être accédées de plusieurs manières :

  • En téléchargeant une bibliothèque de fonctions pour l'inclure sur son site,
  • En récupérant une donnée précise en construisant une URL,
  • En incluant directement la bibliothèque en ligne.

Concernant Google Maps, on est dans ce dernier cas, c'est à dire qu'on va directement inclure la bibliothèque Google Maps dans notre JavaScript.

Inclure Google Maps

Pour inclure les fonctions Google Maps dans notre application, nous ajoutons une balise script dans la partie head de notre page :

<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script>

L'API Google Maps est disponible sous plusieurs déclinaisons, que l'on peut choisir en ajoutant un paramètre à cette URL. Parmi ces paramètres on retrouve :

  • L'utilisation ou non du GPS : sensor,
  • La langue des textes affichés sur la carte : language,
  • Le pays : region.

Dans le cadre de ce tutoriel nous allons simplement activer l'utilisation du GPS avec le paramètre sensor que l'on va passer à true :

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>

Concernant les autres paramètres je vous invite à aller lire la documentation officielle.

Création de la structure de notre page

Notre carte va venir se loger dans un simple div, auquel nous allons attribuer l'idmap_canvas.<div id="map_canvas"></div>. Afin que la carte s'affiche en plein écran, et qu'elle le fasse correctement sur tous les navigateurs, nous allons ajouter les propriétés de style suivantes :

html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map_canvas { width: 100%; height: 100% }

Pour afficher la carte en plein écran avec des valeurs en pourcentages, les navigateurs les plus âgés auront besoin que l'on définisse également en pourcentage la taille des éléments parents. On indique donc également une height: 100% pour la balise body et pour la balise html. Nous allons également ajouter une balise meta dans le head de notre HTML afin que l'utilisateur ne puisse pas réduire ou agrandir la carte :

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

Et voilà ! Nous avons maintenant une page HTML prête à accueillir une Google Map. Voici ce à quoi devrait ressembler votre code pour le moment :

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  <style type="text/css">
    html { height: 100% }
    body { height: 100%; margin: 0px; padding: 0px }
    #map_canvas { height: 100% ; width:100%;}
  </style>
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
</head>
<body>
  <div id="map_canvas"></div>
</body>
</html>

Un rapide aperçu dans le navigateur nous montre... qu'absolument rien ne s'affiche, et c'est tout à fait normal ! Un peu de patience, la magie va agir très bientôt.

Afficher la carte Google Maps

Bien, il est temps de passer aux choses sérieuses ! Nous souhaitons afficher la carte une fois notre page html chargée. Pour cela nous allons ajouter l'attribut onload à notre balise body : <body onload="initialize()">, puis créer la fameuse fonction initialize() dans un script.

<script type="text/javascript">
  function initialize() {

  }
</script>

Cette fonction va, comme son nom l'indique, initialiser la carte Google Maps. Dans le cadre de ce tutoriel, nous allons créer une carte :

  • Contenue dans notre div map_canvas,
  • Centrée sur les coordonnées 48.858565, 2.347198 (Châtelet à Paris !),
  • De niveau de zoom 19 (très précis afin de pouvoir tester facilement les déplacements un peu plus tard),
  • En mode ROADMAP c'est à dire un plan classique, sans image satellite ni relief.

Ces paramètres sont à fournir à l'instanciation de l'objet google.maps.Map :

function initialize() {
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 19,
    center: new google.maps.LatLng(48.858565, 2.347198),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  })
}

Revenons un peu sur ce code...

Tout d'abord, le premier paramètre correspond à l'élément du DOM dans lequel va être injecté notre carte (ici map_canvas, que l'on récupère grâce à document.getElementById()). Ensuite, le second paramètre, les options, doivent être fournies sous cette forme : {nom: valeur, nom: valeur, ...}.

On remarque que les coordonnées du center sont fournies au travers d'un nouvel objet : google.maps.LatLng. Il en sera ainsi dès que l'on voudra définir la latitude et longitude d'une coordonnée. Enfin mapTypeId correspond au type de carte à afficher :

  • ROADMAP pour le plan,
  • SATELLITE pour les photos satellite,
  • HYBRID pour afficher les photos satellites avec le plan superposé,
  • TERRAIN pour afficher les reliefs.

Allez, cette fois on peut ouvrir la page html dans son navigateur et... bingo ! Voilà un beau plan centré sur Châtelet ! Si possible, testez avec un smartphone afin de voir que les boutons de zoom, et de changement de vue apparaissent bien et qu'ils soient de la bonne taille. En effet si vous avez oublié la balise meta ils seront minuscules...

Patience on y arrive... Puisqu'on va maintenant utiliser la géolocalisation HTML5 !

Ajouter la géolocalisation HTML5

Tout d'abord je précise à nouveau qu'il est nécessaire que vous maitrisiez la géolocalisation en HTML5 car ses principes ne seront pas réexpliqués dans ce tutoriel.

Pour commencer, à la suite de la fonction initialize(), nous testons la compatibilité du navigateur avec la géolocalisation HTML :

if (navigator.geolocation)
  var watchId = navigator.geolocation.watchPosition(successCallback, null, {
    enableHighAccuracy: true,
  })
else alert('Votre navigateur ne prend pas en compte la géolocalisation HTML5')

Vous pouvez noter que je n'utilise pas d'errorCallback, ceci afin de ne pas alourdir le code et se concentrer sur l'essentiel. A chaque mise à jour de la position de l'utilisateur, la variable position dans successCallback est mise à jour. De plus, la méthode panTo() permet de centrer la carte sur de nouvelles coordonnées. Par conséquent nous allons ajouter à notre successCallback :

map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude))

Et pour représenter la position exacte, nous allons placer un marqueur sur la carte :

var marker = new google.maps.Marker({
  position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
  map: map,
})

Nous avons donc à présent :

function initialize() {
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 19,
    center: new google.maps.LatLng(48.858565, 2.347198),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  })
}

if (navigator.geolocation)
  var watchId = navigator.geolocation.watchPosition(successCallback, null, {
    enableHighAccuracy: true,
  })
else alert('Votre navigateur ne prend pas en compte la géolocalisation HTML5')

function successCallback(position) {
  map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude))
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
    map: map,
  })
}

A chaque déplacement effectué par l'utilisateur, un nouveau marqueur est placé sur la carte afin d'indiquer votre nouvel emplacement. Sympathique non ?

Notez cependant que si vous faites le test dans la rue avec votre smartphone, dès que le GPS perd le signal, votre position sera replacée au point relais auquel votre 3G est rattachée, ce qui est beaucoup moins précis.

Et voilà ! A ce stade vous avez toutes les connaissances pour exploiter la géolocalisation en HTML5 au travers de l'API Google Maps. Les plus curieux d'entre vous pourront pousser leurs recherches un peu plus loin en parcourant la documentation de l'API Google Maps, afin d'exploiter aux mieux les très nombreuses fonctionnalités proposées par l'API.

Bonus : le tracé du parcours

Vous en voulez encore ? Parfait ! Nous allons ajouter à notre application la cerise sur le gâteau qui épatera vos proches ! (qui ont cependant 9 chances sur 10 de vous répondre "Ben qu'est-ce que ça a de si formidable ? C'est l'application Google Maps quoi...", mais ne perdez pas espoir !).

Afin de parfaire notre application nous allons donc tracer une ligne qui va représenter le chemin suivi par l'utilisateur. Pour ce faire, nous allons avoir recours à l'objet google.maps.Polyline. Un Polyline est une ligne tracée entre plusieurs points. Dans le cadre de cet exemple, à chaque nouvelle position de géolocalisation, nous allons tracer une ligne reliant la position précédente à la nouvelle. Un Polyline se crée de la manière suivante :

var newLine = new google.maps.Polyline({
  path: newLineCoordinates,
  strokeColor: '#FF0000',
  strokeOpacity: 1.0,
  strokeWeight: 2,
})

Les 3 derniers paramètres servent à définir l'apparence du tracé (qui est rouge dans cet exemple), et le premier paramètre est un tableau de coordonnées, c'est à dire :

var newLineCoordinates = [
  new google.maps.LatLng(previousPosition.coords.latitude, previousPosition.coords.longitude),
  new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
]

Cette variable doit être créée avant newLine bien entendu. On remarque la variable previousPosition qui n'est pas encore définie. Nous allons le faire immédiatement en déclarant une variable globale tout en haut de notre script :

var previousPosition = null

Cette variable contiendra en permanence la position précédente afin d'effectuer le tracé du Polyline. Une fois toutes ces informations fournies pour la création du Polyline, il suffit d'ajouter ce dernier à notre carte :

newLine.setMap(map)

Enfin, on attribue la valeur courante de position à previousPosition :

previousPosition = position

Ce qui donne le code suivant :

var previousPosition = null

function initialize() {
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 19,
    center: new google.maps.LatLng(48.858565, 2.347198),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  })
}

if (navigator.geolocation)
  var watchId = navigator.geolocation.watchPosition(successCallback, null, {
    enableHighAccuracy: true,
  })
else alert('Votre navigateur ne prend pas en compte la géolocalisation HTML5')

function successCallback(position) {
  map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude))
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
    map: map,
  })
  if (previousPosition) {
    var newLineCoordinates = [
      new google.maps.LatLng(previousPosition.coords.latitude, previousPosition.coords.longitude),
      new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
    ]

    var newLine = new google.maps.Polyline({
      path: newLineCoordinates,
      strokeColor: '#FF0000',
      strokeOpacity: 1.0,
      strokeWeight: 2,
    })
    newLine.setMap(map)
  }
  previousPosition = position
}

On a également ajouté une condition sur l'existence de la variable previousPosition, afin de ne pas déclencher d'erreur lors de la première exécution du code.

Si vous testez ce code sur votre smartphone, vous remarquerez que chaque coupure du signal GPS provoque le tracé de lignes vers le point très éloigné de votre anterre 3G la plus proche. Afin de pallier à ce défaut, nous pouvons faire appel à l'une des propriétés très intéressantes de l'objet position.coords. Si vous avez bien suivi le précédent tutoriel vous devriez avoir deviné qu'il s'agit de la propriété accuracy !

Afin de ne jamais prendre en compte les coordonnées imprécises du Wifi et de la 3G sans GPS, il nous suffit donc d'ajouter un seuil de précision minimal en mètres qui va englober tout le contenu du successCallback.

function successCallback(position) {
  if (position.coords.accuracy < 100) {
    // Affichage du marqueur et du Polyline
  }
}

Code complet de démonstration

Ce code affiche une carte utilisant l'API Google Maps ainsi que les données de géolocalisation afin de situer l'utilisateur grâce au GPS de son téléphone. L'application affiche le tracé du parcours de l'utilisateur s'il se déplace et place un marqueur à chaque nouvelles coordonnées reçues par le service de géolocalisation :

<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
	  html { height: 100% }
	  body { height: 100%; margin: 0px; padding: 0px }
	  #map_canvas { height: 100% ; width:100%;}
	</style>
	<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>	
	<script type="text/javascript">

		var previousPosition = null;
	
		function initialize() {
			map = new google.maps.Map(document.getElementById("map_canvas"), {
			      zoom: 19,
			      center: new google.maps.LatLng(48.858565, 2.347198),
			      mapTypeId: google.maps.MapTypeId.ROADMAP
			    });		
		}
		  
		if (navigator.geolocation)
			var watchId = navigator.geolocation.watchPosition(successCallback, null, {enableHighAccuracy:true});
		else
			alert("Votre navigateur ne prend pas en compte la géolocalisation HTML5");
			
		function successCallback(position){
			map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
			var marker = new google.maps.Marker({
				position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude), 
				map: map
			});  
			if (previousPosition){
				var newLineCoordinates = [
					 new google.maps.LatLng(previousPosition.coords.latitude, previousPosition.coords.longitude),
					 new google.maps.LatLng(position.coords.latitude, position.coords.longitude)];
				
				var newLine = new google.maps.Polyline({
					path: newLineCoordinates,	       
					strokeColor: "#FF0000",
					strokeOpacity: 1.0,
					strokeWeight: 2
				});
				newLine.setMap(map);
			}
			previousPosition = position;
		};		
	</script>
</head>

<body onload="initialize()">
	<div id="map_canvas"></div>
</body>

</html>

Et voilà c'est terminé ! J'espère que ce tutoriel vous a plu, et qu'il a rendu un peu plus concrète l'utilisation de la géolocalisation en HTML5. C'est vrai qu'avoir des chiffres qui bougent c'est bien, mais une carte c'est mieux !

A très bientôt pour de nouveaux tutoriels !