Script Php de calcul de distances

WRInaute accro
Je cherche un script en PHP pour calculer les distances entre deux villes.

Ce script existe en javascript mais cela ne m'intéresse pas. Si vous connaissez un faites-moi signe SVP. Et si possible avec une base de données conséquentes de villes... pour ne pas avoir à rechercher tout cela :lol:
 
WRInaute passionné
Euh... ça existe, ça ? Ca doit donner un nombre tout à fait incroyable de combinaisons ?

Si tu as mille villes indexées, tu as... euh... un paquet de possibilités. Je n'ai plus fait de stats depuis longtemps, mais c'est énorme.
 
WRInaute impliqué
8O

Effectivement cela doit faire pas mal de combinaisons !!!

Distance à vol d'oiseau, en voiture ( autoroutes ) ou a pied ( petit chemins ). :?:

:?
 
WRInaute passionné
Même en se limitant à une distance arbitraire, c'est énorme...

Entre 3 villes différentes, ça fait 3 possibilités. Là ça va...
Mais pour 5 villes, ça en fait déjà 10...
Pour 10 villes, 45...
Pour 21 villes, 210...
Pour 35 villes, 595...

Et je vous épargne la suite (sous réserve que mes calculs soient bons, ce que je crois).
 
WRInaute impliqué
Il n'y a pas vraiment de combinaisons si tu souhaites calculer la distance a vol d'oiseaux entre les villes.

Il suffit du couple altitude / longitude pour chacune des villes souhaitées et le calcul se fait par algo.

Donc si tu as 5 villes cela te donne 5 lignes dans ton tableaux, 1000 villes pour 1000 lignes...
 
WRInaute passionné
petit-ourson a dit:
Il n'y a pas vraiment de combinaisons si tu souhaites calculer la distance a vol d'oiseaux entre les villes.

A vol d'oiseau, c'est bien sûr différent... mais alors c'est plus un gadget qu'un outil.
 
WRInaute passionné
Americas a dit:
Je cherche un script en PHP pour calculer les distances entre deux villes.

Ah bah quand même...

Je me demandais qu'and le concepteur du calcul des courte distance chez MSN allait demander l'avis de pros :mrgreen:
 
WRInaute impliqué
En voila un en ASP qui donne une distance à vol d'oiseau entre deux points repérés par latitude/longitude en tenant compte de la courbure de la terre...

Code:
dim gPI
gPI = 3.14159265358979

dim gEARTH_RADIUS_METRES
gEARTH_RADIUS_METRES = 6378007

dim gEARTH_CIRCUM_METRES
gEARTH_CIRCUM_METRES = gEARTH_RADIUS_METRES * 2 * gPI

dim gMETRES_PER_LAT_DEGREES
gMETRES_PER_LAT_DEGREES = 111113.519

Function GetDistance(dX1, dY1, dX2, dY2)
    Dim dDeltaX
    Dim dDeltaY
    Dim dDeltaXMeters
    Dim dDeltaYMeters
    Dim dMetersPerDegreeLong
    Dim dCenterY

    dDeltaX = Abs(dX2 - dX1)
    dDeltaY = Abs(dY2 - dY1)
    dCenterY = (dY1 + dY2) / 2
    dMetersPerDegreeLong = MetresPerDegreeLong(dCenterY)
    dDeltaXMeters = dDeltaX * dMetersPerDegreeLong
    dDeltaYMeters = dDeltaY * gMETRES_PER_LAT_DEGREES
    GetDistance = Sqr(dDeltaXMeters ^ 2 + dDeltaYMeters ^ 2)
End Function

Function MetresPerDegreeLong(dLat )
    MetresPerDegreeLong = (Cos(dLat * (gPI / 180)) * gEARTH_CIRCUM_METRES) / 360
End Function

Ca devrait pas être très compliqué à réécrire en PHP
 
WRInaute occasionnel
l'algorythme qui permet de trouver le chemin le plus court (dans un reseau complexe, rien a voir avec le vol d'oiseau) et qui est utilisé dans la pluspart de ce genre d'appli s'appelle l'algorythle de Dijkstra (du nom de son inventeur), une petite recherche sur google avec cet mot devrait vous etre utile :)
 
WRInaute impliqué
Tex a dit:
l'algorythme qui permet de trouver le chemin le plus court (dans un reseau complexe, rien a voir avec le vol d'oiseau) et qui est utilisé dans la pluspart de ce genre d'appli s'appelle l'algorythle de Dijkstra (du nom de son inventeur), une petite recherche sur google avec cet mot devrait vous etre utile :)

Qui a dit chemin le plus court ?
 
WRInaute impliqué
Bon, 2 optiques :
- soit il s'agit de la distance à vol d'oiseau, auquel cas la formule est racine carrée ((x2 - x1)² + (y2 - y1)²)
- soit il s'agit de la distance entre 2 villes en suivant des sections de route dnot on connaît la longueur, auquek cas il s'agit de l'algorithme du chemin minimal entre deux sommets d'un graphe, algorithme que tu trouveras sur Google

NB pour Olivieri : LA distance signifie nécessairement la distance la plus courte, car on peut toujours trouver plus long (en s'amusant à faire un tour pour rien par exemple) ;)
 
WRInaute occasionnel
MarvinLeRouge a dit:
- soit il s'agit de la distance à vol d'oiseau, auquel cas la formule est racine carrée ((x2 - x1)² + (y2 - y1)²)

Valable seulement en métrique, pour des distances courtes...

MarvinLeRouge a dit:
NB pour Olivieri : LA distance signifie nécessairement la distance la plus courte, car on peut toujours trouver plus long (en s'amusant à faire un tour pour rien par exemple) ;)

Et si tu parcours un graphes où les "distances" entre les sommets du graphe sont des temps de parcours, par exemple, eh bien ton calcul du "plus court" correpsond au plus rapide (temps le plus petit) !
 
WRInaute impliqué
Blini a dit:
MarvinLeRouge a dit:
- soit il s'agit de la distance à vol d'oiseau, auquel cas la formule est racine carrée ((x2 - x1)² + (y2 - y1)²)

Valable seulement en métrique, pour des distances courtes...

Comment ça valable seulement pour des distances courtes ? 8O C'est la formule de calcul de la distance du point A au point B dans le plan, et l'ordre de grandeur n'a rien à voir là dedans, pas plus que l'unité employée. A moins que tu ne tiennes compte de la non-planitude de la surface terrestre, mais là il n'est plus question du même argument. :?

Blini a dit:
MarvinLeRouge a dit:
NB pour Olivieri : LA distance signifie nécessairement la distance la plus courte, car on peut toujours trouver plus long (en s'amusant à faire un tour pour rien par exemple) ;)

Et si tu parcours un graphes où les "distances" entre les sommets du graphe sont des temps de parcours, par exemple, eh bien ton calcul du "plus court" correpsond au plus rapide (temps le plus petit) !

Oui, on peut effectivement calculer le temps de parcours minimal selon la même méthode (ce qui en général ne rend pas le même chemin, d'ailleurs :roll: ).
 
WRInaute impliqué
MarvinLeRouge a dit:
Comment ça valable seulement pour des distances courtes ? 8O C'est la formule de calcul de la distance du point A au point B dans le plan, et l'ordre de grandeur n'a rien à voir là dedans, pas plus que l'unité employée. A moins que tu ne tiennes compte de la non-planitude de la surface terrestre, mais là il n'est plus question du même argument. :?
Oui, je crois que c'est cela dont il s'agit...la terre n'est pas un plan, donc sur de grosses distances ce genre de calcul doit être très approximatif, je suppose.
 
WRInaute occasionnel
MarvinLeRouge a dit:
Comment ça valable seulement pour des distances courtes ? 8O C'est la formule de calcul de la distance du point A au point B dans le plan, et l'ordre de grandeur n'a rien à voir là dedans, pas plus que l'unité employée. A moins que tu ne tiennes compte de la non-planitude de la surface terrestre, mais là il n'est plus question du même argument. :?

Oui, la formule, c'est pour le plan. Mais pour les cartes terrestres, deux cas: ou bien tu représentes basiquement les coordonnées sur les axes (degrés-minutes-secondes), et là, pas possible de calculer des distances, ou bien tu as une carte métrique, ce qui suppose que tu as fait une projection. La projection habituelle pour la France est le Lambert IIe (avec des variantes possibles: projections différentes sur 4 parties de la France). Le Lambert IIe, c'est une projection de l'ellipsoïde terrestre sur un cône sécant en deux parallèles de l'ellipsoïde. Je vais peut-être pas rentrer dans les détails, mais grosso modo, plus tu t'éloignes du centre de projection, plus l'erreur est importante. Donc, oui, les calculs de distances par la formule donnée ne sont valables que pour des distances assez courtes.
 
WRInaute impliqué
Nous sommes donc bien d'accord en fait : j'évoquais un cas théorique, que tu as rapporté à la réalité en le pondérant comme il se devait. 8)
 
WRInaute occasionnel
olivieri a dit:
Tex a dit:
l'algorythme qui permet de trouver le chemin le plus court (dans un reseau complexe, rien a voir avec le vol d'oiseau) et qui est utilisé dans la pluspart de ce genre d'appli s'appelle l'algorythle de Dijkstra (du nom de son inventeur), une petite recherche sur google avec cet mot devrait vous etre utile :)

Qui a dit chemin le plus court ?

comme ça n'etait pas explicité j'ai apporté un complement d'information sur l'autre methode tout simplement :)
 
WRInaute accro
Boudiou !!! Comme j'ai mal à la tête après toutes ces explications 8O

Bon... pour faire simple... parce que j'ai rien trouver de convainquant si ce n'est un script en perl sur cette page.

Les résultats du script sont assez probants... même si j'ai pas encore réussi à faire le tourner sur mon site :lol:
Bon... mais sur l'adresse indiquée ça fonctionne bien....

Le seul problème c'est que c'est en perl et je cherche un truc en php :roll:
 
WRInaute occasionnel
Je suis bien d'accord avec toi j'ai lache au bout d'un moment, je ne pensais pas que le calcul de distance etait aussi complexe. Le sujet m"interesse pour retrouver a partir de ma base et dans un rayon de x km a partir d'une ville donnée un professionnel
 
WRInaute occasionnel
Bon désolé d'être rentré dans les détails, mais c'était surtout pour dire que non, on ne peut pas se contenter d'une racine carré de la somme x²+y² pour les distances.
En fait, le plus simple tout en restant grosso modo juste, c'est de prendre effectivement le script http://www.indo.com/distance/dist.pl
Il suppose que la Terre est une sphere avec un rayon moyen choisi de 6367 km. Après, la distance elle-même est calculée en mesurant l'arc de cercle sur cette sphère qui sépare les deux points (les villes).

<culture>Juste pour que tu sois conscient des approximations faites, je rappelle que la Terre est un patatoïde, généralement assimilé à une ellipsoïde plutôt qu'à une sphère (ellipsoïde = sphère applatie aux pôles). Les gars qui font des cartes choisissent donc un ellipsoïde qui leur plait, puis l'emplacement de cet ellipsoïde par rapport au centre de la Terre. Le même ellipsoïde peut être placé différemment, pour minimiser les approximations selon l'endroit dont on veut une carte. La donnée de cet ellipsoïde et de son emplacement s'appelle un "datum". Puis les gars choisissent un système de projection: Mercator, Lambert conique ou conforme ou autre... (certaines projections donnent des cartes qui respectent les distances, d'autres les angles). Enfin, ils appliquent tout ça pour obtenir une carte...
</culture>

Dans le script perl, la seule procédure importante est "great_circle_distance". J'ai pris qqs minutes pour te l'écrire en PHP. Les arguments sont les longitudes et latitudes des 2 villes, exprimées en degrés décimaux signés. Donc pour 25°30'00''E tu passes 25,5° ; pour 43°15'30"S tu passes -43,258° (négatif car coordonnées "sud"). Sur le principe, une coordonnée Ouest ou Sud devient négative. Regarde les fonctions "parse_degrees" et "parse_location" du script original pour ces conversions.
Code:
function get_distance($long1, $lat1, $long2, $lat2)
{
	$earth_radius = 6367000;	// Terre = sphère de 6367km de rayon
	$rlo1 = deg2rad($long1);
	$rla1 = deg2rad($lat1);
	$rlo2 = deg2rad($long2);
	$rla2 = deg2rad($lat2);

	$dlo = ($rlo2 - $rlo1) / 2;
	$dla = ($rla2 - $rla1) / 2;
	$a = (sin($dla) * sin($dla)) + cos($rla1) * cos($rla2) * (sin($dlo) * sin($dlo));
	$d = 2 * atan2(sqrt($a), sqrt(1 - $a));

	return ($earth_radius * $d);
}
Remarque: c'est juste un portage du code, je n'ai pas regardé l'exactitude de la formule.

Et si par ailleurs tu as une base avec les coordonnées lat/long des villes, c'est tout bon...
 
WRInaute passionné
Blini, tu cartonnes !

Je vois peut-être bien une utilisation potentielle de ce script...
Merci.
 
WRInaute passionné
Je viens de tester... ça fontionne nickel ! Je te dois désormais une reconnaissance éternelle ;-)
 
WRInaute accro
Super en effet... le seul problème c'est que j'arrive pas à utiliser ce script :lol:

Bon... aK et Blini... concrètement... un code en ordre de marche ... ça donnerait quoi ?

Je vous l'avais déjà dit que je suis une brelle en PHP :oops:

J'ai besoin d'un formulaire qui appelle le script comme dans le script que j'avais indiqué plus haut...

ou l'autre possibilité... deux listes déroulantes de villes prédéterminées pour le départ et l'arrivée :roll:
 
WRInaute passionné
Le script fonctionne nickel comme ça... faut juste entrer des paramètres dans la fonction (les 2 latitudes et les 2 logitudes) et elle te sort la distance.

Donc si t'as les coordonnées géographiques de 2 villes, tu fais:

Code:
print get_distance($longitude_paris, $latitude_paris, $longitude_bruxelles, $latitude_bruxelles);

et ça te sort 200 kilomètres et des brouettes (sauf qu'elle te les sort en mètres).
 
WRInaute accro
D'accord pour des distances prédéterminées... mais je veux laisser la possibilité aux visiteurs de calculer un itinéraires entre les villes d'@mérique L@tine.

Ils sont sur une page "colombi@" par exemple... et ils veulent chercher la distance entre Bogot@, Me@dellin, C@li... etc...

Il me faut donc un formulaire pour les laisser entrer ces villes... ou mieux... trouver la distance entre une ville de Colombi@ et une d'un autre pays latin@ :wink:
 
WRInaute occasionnel
Je crois qu'Americas attend un script tout fait, une page toute faite, même, avec un formulaire où tu saisies le noms des deux villes.
Bon, sans vouloir faire de pub, mais quand même, il y a www.mappy.com qui est là pour ça (distances réelles par la route) :)
Sinon, il faut trouver une BdD avec le nom des villes et leur position lat/long, un petit <form> dans une page, une requête mysql, et un appel à la fameuse "get_distance"...
Americas, tu peux sûrement trouver un squelette de page PHP avec un formulaire, puis l'adapter, non ?
Sinon, pour une BdD avec les coordonnées des villes, ça m'a tout l'air d'être dispo gratis ici:
http://earth-info.nga.mil/gns/html/cntry_files.html
Bon, il faut lire un peut pour comprendre les champs des fichiers texte, mais ça devrait être faisable...
Sinon, trouvé aussi ici:
http://jyotisha.00it.com/Latitude.htm
 
WRInaute accro
C'est vrai... je suis un grand paresseux :oops:

Bon... on va essayer de se débrouiller :wink:

Quant à la bdd... je la laisse où elle est... 700 Mo déployée... j'ai pas envie d'installer cette usine à gaz moi :lol:
 
Nouveau WRInaute
Moi, je me suis servis de l'API Google Map pour effectuer ce calcul de manière plus précise !

PHP:
<span class="syntaxdefault"><br />&nbsp;&nbsp;&nbsp;&nbsp;$dom </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> new DOMDocument</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">    $dom</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">validateOnParse </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> true</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">    <br />    $APIMAP </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'http://maps.googleapis.com/maps/api/distancematrix/xml?origins='</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$provenance</span><span class="syntaxkeyword">.</span><span class="syntaxstring">'&destinations='</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$destination</span><span class="syntaxkeyword">.</span><span class="syntaxstring">'&sensor=false'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">    <br />    $dom</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">load</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$APIMAP</span><span class="syntaxkeyword">);</span><span class="syntaxdefault"> <br />    <br />    <br />    $elemlist</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">$dom</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">getElementsByTagName</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'distance'</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">    <br />    if </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$elemlist</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">length </span><span class="syntaxkeyword">!=</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">        &nbsp;   $elementDistance </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> $elemlist</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">item</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">        &nbsp;&nbsp;&nbsp; $valeurKmlist</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">$elementDistance</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">getElementsByTagName</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'value'</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">            if </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$valeurKmlist</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">length</span><span class="syntaxkeyword">!=</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">            </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">                    $valeurKm</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">$valeurKmlist</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">item</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">);</span><span class="syntaxdefault">            <br />                    $resultatEnMetre </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> $valeurKm</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">firstChild</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">nodeValue</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">                    $resultatkm </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> ceil</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$resultatEnMetre </span><span class="syntaxkeyword">/</span><span class="syntaxdefault"> 1000</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">           </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">}</span><span class="syntaxdefault"> </span>

$resultatkm contient la valeur en km correspondant a la distance séparant $provenance et $destination.
De cette manière, il suffit d'envoyer dans le script la ville précéder de son code postal pour avoir une réponse, et pas besoin de s'encombrer avec des latitudes et longitudes.
 
Discussions similaires
Haut