[OpenLayers] Afficher un itinéraire calculé avec l’API Google Maps
Quand on est un peu familier avec les API de Google, afficher un itinéraire Google Maps dans une carte Google Maps est un jeu d’enfant car tout est déjà prévu pour vous rendre accro aux produits Google faciliter la tâche ! Voici un petit tuto pour afficher facilement, dans une carte OpenLayers, un itinéraire calculé par Google Maps !
1) Récupérer l’itinéraire en PHP ou en JS
En JS, il faut commencer par appeler l’API Google Maps. Pour ce faire, il vous faudra une clef d’API légalement obtenue (délivrée sur simple demande). La subtilité, ici, est d’appeler une librairie complémentaire (« geometry »), mais nous en reparlerons plus tard…
<script src="https://maps.googleapis.com/maps/api/js?key=pL34s3_g3t_y0uR_0wN_k3y&libraries=geometry&sensor=false"></script>
Ensuite, il faut demander gentiment à Google de calculer notre itinéraire :
var adresse_depart = 'paris'; var adresse_arrivee = 'poitiers'; var encoded_polyline; var directionsService = new google.maps.DirectionsService(); directionsService.route({origin:adresse_depart, destination:adresse_arrivee, travelMode:google.maps.TravelMode.DRIVING},function(result, status){ if(status == google.maps.DirectionsStatus.OK) { encoded_polyline = result['routes'][0]['overview_polyline']['points']; } });
En PHP, il suffit d’appeler une URL avec les bons paramètres qui vont bien et, hop, on a bel objet JSON prêt à être utilisé. Parmi toutes les informations contenues par ce JSON, on ne va s’intéresser qu’à une seule donnée :
$origine = 'paris'; $destination = 'poitiers'; $appel_api = file_get_contents('http://maps.googleapis.com/maps/api/directions/json?origin='.$origine.'&destination='.$destination.'&sensor=false'); $itineraire = json_decode($appel_api); $encoded_polyline = $itineraire->routes[0]->overview_polyline->points
Donc, ce qui nous intéresse ici, c’est le contenu de la dernière variable (que nous avons appelé « encoded_polyline »), à savoir une chaîne de caractères un peu bizarre :
aph{GepaAnKcSlAqQuOoc@eYrCaZ|TyLvf@uJfZ_[fDoX}S}\y[wfAee@}OeAcGiAjB_HnCfh@o@ ...
Mais cette chose immonde au premier abord est en fait une « overview_polyline », c’est à dire le résumé (encodé) de la géométrie de votre itinéraire – des points qui la composent, pour être plus précis !
Toute la (faible) complexité de notre mission réside donc dans le décodage de cette chaîne de caractère. Et, là encore, c’est Google qui va le faire le boulot !
2) Préparons la carte OpenLayers
Un peu de JS pour avoir une carte OpenLayers à disposition…
var cartographie; var epsg_4326 = new OpenLayers.Projection("EPSG:4326"); var epsg_3857 = new OpenLayers.Projection("EPSG:3857"); cartographie = new OpenLayers.Map('carte'); // Couche "OSM" var couche_osm = new OpenLayers.Layer.OSM('OpenStreetMap'); cartographie.addLayer(couche_osm); cartographie.setCenter(new OpenLayers.LonLat(2, 48).transform(epsg_4326, epsg_3857), 7); // Couche "Itinéraires" var couche_itineraires = new OpenLayers.Layer.Vector('Itinéraires',{styleMap:new OpenLayers.StyleMap({'default':new OpenLayers.Style({strokeWidth:2,strokeColor:'red'})})}); cartographie.addLayer(couche_itineraires);
3) Transformation de l’itinéraire Google Maps en ligne classique
Comme prévu, il ne nous reste plus qu’à demander à l’API JS de Google Maps de décoder la chaîne de caractères (notre variable encoded_polyline, souvenez-vous…). Pour cela, il faut appeler cette API, en n’oubliant pas la librairie complémentaire « geometry » (cf. calcul de l’itinéraire en JS au début du tutoriel) !
<script src="https://maps.googleapis.com/maps/api/js?key=pL34s3_g3t_y0uR_0wN_k3y&libraries=geometry&sensor=false"></script>
Ensuite, on fait décoder la chaîne par l’API, qui va nous retourner un tableau de points projetés en WGS84. On va parcourir ce tableau pour reconstruire notre propre tableau de points reprojetés en Google Spherical Mercator (ex-900913, ex-3875 et actuel EPSG:3857) :
var decoded_polyline = google.maps.geometry.encoding.decodePath(encoded_polyline); var points = new Array(); for(var i in decoded_polyline) { // On récupère les deux coordonnées en WGS84 pour en faire un objet "Point" correctement reprojeté var lonlat = new OpenLayers.LonLat(decoded_polyline[i].lng(), decoded_polyline[i].lat()).transform(epsg_4326, epsg_3857); var point = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat); // On ajoute ce point à notre tableau de points points.push(point); } // On ajoute, à notre couche d'itinéraires, un objet "Ligne" construit à partir du tableau de "Points" couche_itineraires.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points))]); cartographie.zoomToExtent(couche_itineraires.getDataExtent());
Si vous êtes partis de l’exemple en JS au début du tutoriel, attention à bien mettre ce bloc de code dans le bloc if(), juste derrière l’assignation de la variable « encoded_polyline », car des appels asynchrones compliquent notre affaire…
Et voilà ! C’est déjà fini ! Elle est pas belle la vie ?
Allez, je vous donne un exemple complet (en JS) : copiez le code-source, mais pensez à changer la clef de l’API Google Maps !
Bonjour,
J’ai lu attentivement votre tutoriel, en fait cela fait longtemps que je cherche comment intégrer l’itinéraire calculé par google maps V3 dans une couche d’OpenLayers, mais en vain.
Donc j’ai essayé votre code, avant de l’intégrer dans mon application, j’ai essayé tout simplement le code de votre exemple sur le lien http://labs.adrienvh.fr/blog/ol_itineraire_google_maps/ par la suite j’ai changé la clé de l’api google maps, mais rien n’est affiché.
En quoi réside t-il le problème, je serai vraiment reconnaissant !!
Bonjour,
Je réponds à Mr Aissam pour l’aider à faire fonctionner cette carte.
Supprimer : encoded_polyline = result[‘routes’][0][‘overview_polyline’][‘points’];
Et à la place :
var decoded_polyline = result[‘routes’][0][‘overview_path’];
var points = new Array();
Cordialement
LL
Merci pour l’info !
bonjour, les liens ne sont pas fonctionnels