Astuces de Webmaster

PHP : Distance en KM grâce à Google Maps API Directions

par Rom's le 21 août 2010 (Développement Web)

Petite fonction pour calculer la distance entre un point A et un point B grâce à l’API de Google Maps qui a été récemment ouverte pour les itinéraires (Google Maps API Directions).

Vous pouvez ainsi récupérer la distance d’un trajet, sa durée (temps de trajet), les étapes et l’adresse convertie de départ et d’arrivée (permet de récupérer une adresse postale par rapport à des coordonnées)

Vous avez ainsi la distance réelle en kilomètres par la route et non à vol d’oiseau !

function getDistance($adresse1,$adresse2) {
$url='http://maps.google.com/maps/api/directions/xml?language=fr&origin='.$adresse1.'&destination='.$adresse2.'&sensor=false';
$xml=file_get_contents($url);
$root = simplexml_load_string($xml);
$distance=$root->route->leg->distance->value;
$duree=$root->route->leg->duration->value;
$etapes=$root->route->leg->step;
return array(
'distanceEnMetres'=>$distance,
'dureeEnSecondes'=>$duree,
'etapes'=>$etapes,
'adresseDepart'=>$root->route->leg->start_address,
'adresseArrivee'=>$root->route->leg->end_address
);
}

Le guide from Google est par là : http://code.google.com/intl/fr-FR/apis/maps/documentation/directions/

ATTENTION : GOOGLE ACCEPTE UN NOMBRE LIMITE DE REQUETES (sous peine d’un status : OVER_QUERY_LIMIT). Si vous souhaitez récupérer plusieurs résultats à la suite, Il faut donc soit temporiser les requêtes et en faire une toutes les 100ms (100 millisecondes soit 100000 microsecondes, source : un script exemple de google utilise ce délai), soit suivre une méthode que je vous proposer bientôt ici même (mise en cache). Il est important de le faire dès le départ, j’en ai fait l’amère expérience, mon IP personnelle est blacklistée de façon permanente apparemment.. (suite à deux fois une dizaine de requêtes simultanées, il ne faut pas grand chose…)

:, , , , , ,


» Flux RSS du blog

26 Commentaires pour cet article

  • citronbleu-v

    Arg moi aussi je me suis fait bloqué avec le OVER_QUERY_LIMIT. Quelqu’un à trouvé comment le débloquer ?

  • Rom's

    Malheureusement, une seule chose à faire : attendre ;-)

  • citronbleu-v

    Combien de temps tu as attendu ? 24h, plusieurs jours ?

    Je vais essayer avec un usleep(200000) pour faire large à chaque tour de boucle sur un autre serveur en espérant que ça marche (enfin que je ne sois pas bloqué).

    Merci en tout cas pour ton tutau très pratique.

  • Rom's

    Je crois que j’ai attendu deux ou trois heures avant d’être débloqué. Mais il ne faut faire aucune tentative entre temps :-)

  • Insigma

    Salut,

    Merci pour ce billet qui m’a bien aidé !
    J’ai néanmoins un problème : par défaut, il récupère le trajet le plus rapide, est-il possible, à ton avis, de récupérer le trajet le plus court à la place ?

    Merci !
    Stan

  • Rom's

    Salut Stan,

    Tu devrais regarder du côté du paramètre « alternatives » ici : http://code.google.com/intl/fr-FR/apis/maps/documentation/directions/#RequestParameters

    Tiens nous au courant ;-)

  • Jean

    Bonjour, je ne vois pas comment passer une latitude/longitude plutot qu’une adresse.. qq pourrait-il m’aider ?

  • Rom's

    Tu mets latitude,longitude (avec la virgule) à la place de l’adresse..

  • Jean

    Merci beaucoup !

  • Marc-André

    Bonjour, j’ai essayé le script et sa marche bien quand je spécifie 2 nom de ville, mais quand je désire une adresse complète avec le nom de rue et numéro de porte il m’affiche un paquet d’erreur:
    Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 22: parser error : AttValue:  » or ‘ expected in …

    Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in …

    Est-ce qu’il y a une syntaxe précise a respecter ?

  • Rom's

    tu dois passer des caractères inacceptables en XML, essaie des htmlspecialchars ou htmlentities ou qq chose dans ce genre ?

  • Marc-André

    Oui j’ai essayé déja et sans succès…
    Sans aucun caractere spéciaux, il semble ne pas vouloir accepter un simple espace entre 2 mots.

  • Marc-André

    Je crois avoir trouvé l’astuce, remplacer les espaces par un « + » dans l’url. :)

  • fleurette

    Salut,
    Article très intéressant !
    Je viens de tomber dessus en cherchant à optimiser des trajets : chercher dans quel ordre parcourir un nombre fini d’étapes (4 ou 5) pour que le trajet soit le plus court possible …
    Mais en regardant de plus près, je crois bien que je n’ai pas le droit de demander plusieurs trajet côté serveur pour n’afficher au client que le plus court, en effet Google précise que tous les résultats de recherche doivent être explicitement affichés au client …
    Ai-je bien compris ?

  • Rom's

    Salut,

    merci.. regarde bien le retour fait par Google : de mémoire, il propose des trajets alternatifs normalement en indiquant à chaque fois la durée et le kilométrage. tiens nous au courant ! :-)

  • MOmox

    Moi, ma question est :

    Est il judicieux celon vous d’implémenter ce code dans un panier virtuel afin de trouver le point de relais le plus proche de l’adresse de l’acheteur (la distance la moins longue)? Sachant que ce qui me fait peur est le délais necessaire à mettre en place pour que google ne vous blackliste pas.

    Si oui, alrs comment mettre en place le délais dans la fonction ci-dessus?

  • MaxSmall

    Bonjour,

    J’aurais voulu savoir si tu as eu le temps de faire le même script avec la mise en cache ou autre car j’aurais besoin d’utiliser cette fonction dans une boucle sql afin d’afficher une 20e de lieux avec la distance par rapport à l’utilisateur.
    Et biensûr avec la limite de requête ben j’arrive vite fais en OVER_QUERY_LIMIT.

    Je passe par une page qui appel ce script (boucle) à chaque fois que l’utilisateur visite cette page.

    MERCI

  • Rom's

    @MOmox => à la demande via un bouton, vous limiterez le nombre de requêtes à ceux qui sont vraiment intéressés

    @MaxSmall => il n’est pas très compliqué de faire un cache via une base ou un fichier txt :

    # si existe dans le fichier (ou la BDD), le récupérer
    # sinon l’ajouter au fichier
    # l’utiliser

  • abdel

    Bonjour
    Cela fait un moment que je cherche une solution de ce type , emballé au début mais rapidement déçu car la fonction ne marche pas , elle ne me renvoie rien !! j’ai essayé le lien directement dans le navigateur , il marche si on donne juste les ville par contre pour des adresses , il renvoie Not found !! exemple de requêtes :
    « http://maps.google.com/maps/api/directions/xml?language=fr&origin=130+rue+du+général+de+gaulle+95370+Montigny+les+cormeilles+France&destination=92+rue+du+général+de+gaulle+92800+puteaux+France&sensor=false »
    Pour le lancement dans un php , je suis sceptique car d’après ma lecture de l’api , google exige qu’on affiche les résultats à l’écran et tout ce que j’ai trouvé sur le net c’est du javascript pour faire des calculs !! merci d’avance pour votre aide .
    Cordialement

  • Maxime

    Je me suis fait bannir aussi, j’espère pas de façon « permanente » ! Du nouveau sur ce script de cache? Ce serait une solution intéressante. Je suis en train d’implémenter la solution ci-dessus avec la pause de 100 ms, je vais pouvoir faire un retour bientôt, pour savoir si cette pause empêche le bannissement à tout jamais… pour essayer ensuite de la baisser un peu

  • Epineus

    Merci mec. Combiné avec l’API flash, ça marche du tonnerre!

  • nono

    bonjour
    j’ai un petit soucis, quand je rentre une ville avec un faute orthographe ou une ville que l’api ne connait pas exemple Lourde (31510) alors qu’elle existe, j’ai un message d’erreur.
    Comment éviter cette erreur.
    Merci

  • Rom's

    Bonjour,
    essayez de toujours faire la requête sous la forme « ville, france »
    « lourde, france » devrait fonctionner ?

  • nono

    bonjour,
    j’ai essayer votre solution, mais ça ne marche pas. j’ai une erreur de type: Trying to get property of non-object in C:\wamp\www\…sur la fonction

  • Rom's

    @nono il faut inscrire l’erreur complète car là on ne comprend rien.. et aussi montrer la ligne qui est concernée dans le code sinon on ne pourra rien t’expliquer.

    Bien vérifier que simplexml est activé comme librairie dans php…

  • nono

    Rom’s voici l’erreur au complet:
    Notice: Trying to get property of non-object in C:\wamp\www\distance\fonctionDistance.php on line 8
    Call Stack
    # Time Memory Function Location
    1 0.0014 468976 {main}( ) ..\index.php:0
    2 0.0702 483872 getDistance( ) ..\index.php:147
    voici la ligne 8 de la fonction:

    $distance=$root->route->leg->distance->value;

    sachant que je vous montre qu’une seule erreur, car la liste(memes erreurs) se rapporte à chaque variable de l’API
    *là c’est la ligne 147 de l’index:

    $dist= getDistance($_SESSION['d'], $_SESSION['a']);

    là je recupere le resultat dans une variable que j’exploite. Marche tres bien pour la plus part des villes, à part pour lourde sans s qui apparementn’est pas dans la base de données de l’api google et pour les fautes d’orthographe sur les villes. Comment contrer cette erreur directement dans la l’api?
    merci

1 Lien vers cet article

Laisser un commentaire


8 - = two

Vous cherchiez ?

Recherche rapide :

Vous ne trouvez toujours pas ? Laissez un petit commentaire sur un article, qu'on puisse regarder ça de plus près !