ville aux alentours d'un point X

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : ville aux alentours d'un point X

Re: ville aux alentours d'un point X

par AB » 29 sept. 2009, 23:53

Ok merci pour le retour, je regarderai ça plus tard :)

Si ton pb est résolu n'oublies pas de cliquer sur une case à cocher verte (en haut à droite des messages) pour indiquer qu'il est résolu ce qui permettra de signaler aux visiteurs qu'il contient une solution :wink:

Re: ville aux alentours d'un point X

par bobmeers » 29 sept. 2009, 22:22

un tout grand merci
probleme resolu donc
http://earth.google.fr/userguide/v4/ug_importdata.html
http://www.phpcs.com/forum/sujet-COORDO ... 76751.aspx


Google Maps propose également un autre service de géocoding, cette fois ci non pas en Javascript mais sous la forme d'un service web REST. Son utilisation est simplissime, et d'une puissance incroyable. Un exemple tout simple consiste à récupérer les coordonnées géographiques (latitude, longitude) correspondant à une adresse.

Voici un exemple en PHP. Il requiert une clé Google Maps pour fonctionner.
/**
* Recherche les coordonnées d'une adresse avec le service Google Maps
* @param adresse string
* @return array(id_result => array(adresse_complete, latitude, longitude))
*/
function get_coordonees_from_adresse($adresse)
{
  $adresse = urlencode($adresse);
  $url = 'http://maps.google.com/maps/geo?q=' . $adresse . '&output=xml&oe=utf8&gl=fr&sensor=false&key=' . GMAP_KEY;
  $page = file_get_contents($url);
  // Parse le résultat XML
  $xml_result = new SimpleXMLElement($page);
  // Vérifie que la requête a réussi
  if ($xml_result->Response->Status->code != 200) return array();
  // Charge les adresses
  $adresses = array();
  foreach ($xml_result->Response->Placemark as $place) {
    list($longitude, $latitude, $altitude) = explode(',', $place->Point->coordinates);
    // Ajoute au tableau
    $adresses[] = array('adresse_complete' => utf8_decode($place->address),
             'latitude' => $latitude,
             'longitude' => $longitude);
  }
  return $adresses;
} 
Cette fonction renvoie un tableau contenant, pour chaque résultat (il peut y'en avoir plusieurs en cas d'ambiguité) l'adresse trouvée (pratique pour différencier plusieurs résultats) et la latitude/longitude.

Re: ville aux alentours d'un point X

par AB » 29 sept. 2009, 21:35

T'as de la chance j'ai fait ça il y quelques années.

J'ai pas le temps de documenter le code et je te le met brut de fonderie. Mais au moins tu auras la classe que j'avais utilisée pour ça et son origine.

Dans mon exemple les coordonnées des communes françaises étaient enregistrées dans plusieurs tables d'où les requêtes.

En échange j'aimerais bien que tu me donnes des infos sur la création de ce "fichier code postaux qui contient la longitude et la latitude de chaque commune grace à un logiciel trouvé sur le net qui récupère ces données sur google earth" car ma bdd avait quelques erreurs :wink:
<?php
// This code was converted to PHP from Visual C++
// by Steven Brendtro on behalf of imaginerc.com

// The original code and an article can be found
// on CodeGuru at:
// http://www.codeguru.com/Cpp/Cpp/algorithms/print.php/c5115/

// Example Usage:
//   $oGC = new GeoCalc();
//   print "GCDistance: " . $oGC->GCDistance(38.9333,-94.3253,38.9314,-94.4876) . "<br />\n";
//   print "GCAzimuth: " . $oGC->GCAzimuth(38.9333,-94.3253,38.9314,-94.4876) . "<br />\n";
//   print "ApproxDistance: " . $oGC->ApproxDistance(38.9333,-94.3253,38.9314,-94.4876) . "<br />\n";
//   print "EllipsoidDistance: " . $oGC->EllipsoidDistance(38.80126649,-94.44590241,43.3368,-96.8755) . "<br /><br />\n";
//   print "EllipsoidDistance In Miles: " . ConvKilometersToMiles($oGC->EllipsoidDistance(38.80126649,-94.44590241,43.3368,-96.8755));

class GeoCalc {

  var $PI = 3.14159265359;
  var $TWOPI = 6.28318530718;
  var $DE2RA = 0.01745329252;
  var $RA2DE = 57.2957795129;
  var $ERAD = 6378.135;
  var $ERADM = 6378135.0;
  var $AVG_ERAD = 6371.0;
  var $EPS = 0.000000000005;
  var $KM2MI = 0.621371;
  var $FLATTENING =  0;

  function GeoCalc() {
  	$this->FLATTENING = 1.0/298.26;  // Earth flattening
                                     // (WGS 1972)
    return;
  }

  function GCDistance($lat1, $lon1, $lat2, $lon2) {
    $lat1 *= $this->DE2RA;
    $lon1 *= $this->DE2RA;
    $lat2 *= $this->DE2RA;
    $lon2 *= $this->DE2RA;
    $d = sin($lat1)*sin($lat2) + cos($lat1)*cos($lat2)*cos($lon1 - $lon2);
    return ($this->AVG_ERAD * acos($d));
  }


  function GCAzimuth($lat1, $lon1, $lat2, $lon2) {
    $result = 0.0;

    $ilat1 = intval(0.50 + $lat1 * 360000.0);
    $ilat2 = intval(0.50 + $lat2 * 360000.0);
    $ilon1 = intval(0.50 + $lon1 * 360000.0);
    $ilon2 = intval(0.50 + $lon2 * 360000.0);

    $lat1 *= $this->DE2RA;
    $lon1 *= $this->DE2RA;
    $lat2 *= $this->DE2RA;
    $lon2 *= $this->DE2RA;

    if (($ilat1 == $ilat2) && ($ilon1 == $ilon2)) {
      return result;
    }
    else if ($ilat1 == $ilat2) {
      if ($ilon1 > $ilon2)
        $result = 90.0;
      else
        $result = 270.0;
    }
    else if ($ilon1 == $ilon2) {
      if ($ilat1 > $ilat2)
        $result = 180.0;
    }
    else {
      $c = acos(sin($lat2)*sin($lat1) + cos($lat2)*cos($lat1)*cos(($lon2-$lon1)));
      $A = asin(cos($lat2)*sin(($lon2-$lon1))/sin($c));
      $result = ($A * $this->RA2DE);


      if (($ilat2 > $ilat1) && ($ilon2 > $ilon1)) {
        $result = $result;
      }
      else if (($ilat2 < $ilat1) && ($ilon2 < $ilon1)) {
        $result = 180.0 - $result;
      }
      else if (($ilat2 < $ilat1) && ($ilon2 > $ilon1)) {
        $result = 180.0 - $result;
      }
      else if (($ilat2 > $ilat1) && ($ilon2 < $ilon1)) {
        $result += 360.0;
      }
    }

    return $result;
  }

  function ApproxDistance($lat1, $lon1, $lat2, $lon2) {
    $lat1 = $this->DE2RA * $lat1;
    $lon1 = -$this->DE2RA * $lon1;
    $lat2 = $this->DE2RA * $lat2;
    $lon2 = -$this->DE2RA * $lon2;

    $F = ($lat1 + $lat2) / 2.0;
    $G = ($lat1 - $lat2) / 2.0;
    $L = ($lon1 - $lon2) / 2.0;

    $sing = sin($G);
    $cosl = cos($L);
    $cosf = cos($F);
    $sinl = sin($L);
    $sinf = sin($F);
    $cosg = cos($G);

    $S = $sing*$sing*$cosl*$cosl + $cosf*$cosf*$sinl*$sinl;
    $C = $cosg*$cosg*$cosl*$cosl + $sinf*$sinf*$sinl*$sinl;
    $W = atan2(sqrt($S),sqrt($C));
    $R = sqrt(($S*$C))/$W;
    $H1 = (3 * $R - 1.0) / (2.0 * $C);
    $H2 = (3 * $R + 1.0) / (2.0 * $S);
    $D = 2 * $W * $this->ERAD;
    $return = ($D * (1 + $this->FLATTENING * $H1 * $sinf*$sinf*$cosg*$cosg - $this->FLATTENING*$H2*$cosf*$cosf*$sing*$sing));
    return $return;
  }

  function EllipsoidDistance($lat1, $lon1, $lat2, $lon2) {
	$distance = 0.0;
	$faz = 0.0;
	$baz = 0.0;
	$r = 1.0 - $this->FLATTENING;
	$tu1 = 0.0;
	$tu2 = 0.0;
	$cu1 = 0.0;
	$su1 = 0.0;
	$cu2 = 0.0;
	$x = 0.0;
	$sx = 0.0;
	$cx = 0.0;
	$sy = 0.0;
	$cy = 0.0;
	$y = 0.0;
	$sa = 0.0;
	$c2a = 0.0;
	$cz = 0.0;
	$e = 0.0;
	$c = 0.0;
	$d = 0.0;

	$cosy1 = 0.0;
	$cosy2 = 0.0;

	if(($lon1 == $lon2) && ($lat1 == $lat2))
	  return $distance;
	$lon1 *= $this->DE2RA;
	$lon2 *= $this->DE2RA;
	$lat1 *= $this->DE2RA;
	$lat2 *= $this->DE2RA;

	$cosy1 = cos($lat1);
	$cosy2 = cos($lat2);

	if($cosy1 == 0.0) $cosy1 = 0.0000000001;
	if($cosy2 == 0.0) $cosy2 = 0.0000000001;

	$tu1 = $r * sin($lat1) / $cosy1;
	$tu2 = $r * sin($lat2) / $cosy2;
	$cu1 = 1.0 / sqrt($tu1 * $tu1 + 1.0);
	$su1 = $cu1 * $tu1;
	$cu2 = 1.0 / sqrt($tu2 * $tu2 + 1.0);
	$x = $lon2 - $lon1;

	$distance = $cu1 * $cu2;
	$baz = $distance * $tu2;
	$faz = $baz * $tu1;

   while(abs($d - $x) > $this->EPS) {
		$sx = sin($x);
		$cx = cos($x);
		$tu1 = $cu2 * $sx;
		$tu2 = $baz - $su1 * $cu2 * $cx;
		$sy = sqrt($tu1 * $tu1 + $tu2 * $tu2);
		$cy = $distance * $cx + $faz;
		$y = atan2($sy, $cy);
		$sa = $distance * $sx / $sy;
		$c2a = - $sa * $sa + 1.0;
		$cz = $faz + $faz;
		if($c2a > 0.0) $cz = - $cz / $c2a + $cy;
		$e = $cz * $cz * 2.0 - 1.0;
		$c = ((-3.0 * $c2a + 4.0) * $this->FLATTENING + 4.0) * $c2a * $this->FLATTENING / 16.0;
		$d = $x;
		$x = (($e * $cy * $c + $cz) * $sy * $c + $y) * $sa;
		$x = (1.0 - $c) * $x * $this->FLATTENING + $lon2 - $lon1;
	}

	$x = sqrt((1.0 / $r / $r - 1.0) * $c2a + 1.0) + 1.0;
	$x = ($x - 2.0) / $x;
	$c = 1.0 - $x;
	$c = ($x * $x / 4.0 + 1.0) / $c;
	$d = (0.375 * $x * $x - 1.0) * $x;
	$x = $e * $cy;
	$distance = 1.0 - $e - $e;
	$distance = (((($sy * $sy * 4.0 - 3.0) * $distance * $cz * $d / 6.0 - $x) * $d / 4.0 + $cz) * $sy * $d + $y) * $c * $this->ERAD * $r;

    return $distance;
  }

  function getKmPerLonAtLat($dLatitude) {
    // Thanks to Eric Iverson for this correction!  Must convert degrees to radians...
    $dLatitude *= $this->DE2RA;
    return 111.321 * cos($dLatitude);
  }

  function getLonPerKmAtLat($dLatitude) {
    return 1 / $this->getKmPerLonAtLat($dLatitude);
  }

  function getKmPerLat() {
    return 111.000;
  }

  function getLatPerKm() {
    return 1 / $this->getKmPerLat();
  }

}

function ConvKilometersToMiles($dValue) {
	return $dValue / 1.609344;
}

//fin de géolocalisation


// DANS CET EXEMPLE JE CHERCHE TOUTES LES COMMUNES DANS UN RAYON DE 33 KM AUTOUR DU CODE POSTAL 63000


$query = "SELECT lon, lat FROM geoloc WHERE id IN (SELECT id FROM codes_postaux_communes WHERE code_postal = '63000') LIMIT 1";
$Result = mysql_query($query);

$comptip = mysql_fetch_assoc($Result) ; //print_r($comptip);

echo '<br />';

$oGC = new GeoCalc();

        // Define the center of the search bounds...
        $dLongitude = $comptip['lon'];
        $dLatitude = $comptip['lat'];

        // Define the maximum search distance
        $dRadius = 33.00;  // in kilometers

        // Calculate the boundary distance in degrees longitude / latitude
        $dAddLat = $oGC->getLatPerKm() * $dRadius;
        $dAddLon = $oGC->getLonPerKmAtLat($dLatitude) * $dRadius;

        // Calculate the boundaries
        $dNorthBounds = $dLatitude + $dAddLat;
        $dSouthBounds = $dLatitude - $dAddLat;
        $dWestBounds = $dLongitude - $dAddLon;
        $dEastBounds = $dLongitude + $dAddLon;

        print "Center Longitude: $dLongitude\n";
        print "Center Latitude: $dLatitude\n";
        print "Radius: $dRadius kilometers\n";

        print "North Bounds: $dNorthBounds\n";
        print "South Bounds: $dSouthBounds\n";
        print "East Bounds: $dEastBounds\n";
        print "West Bounds: $dWestBounds\n";
		
		echo '<br />';
		
	
        $strQuery = "SELECT codes_postaux_communes.code_postal, communes.nom FROM codes_postaux_communes 
		LEFT JOIN communes ON codes_postaux_communes.commune_id = communes.id
		 WHERE codes_postaux_communes.id IN " .
					"(SELECT id FROM geoloc " .
                    "WHERE lat > $dSouthBounds " .
                    "AND lat < $dNorthBounds " .
                    "AND lon > $dWestBounds " .
                    "AND lon < $dEastBounds) ";
		
		//echo $strQuery;		
		$Result2 = mysql_query($strQuery);
		

while ($comptip2 = mysql_fetch_assoc($Result2)) print_r($comptip2);	echo'<br /><br />';

Re: ville aux alentours d'un point X

par zeus » 29 sept. 2009, 20:37

Pas de soucis.
Bien que le fond des messages que j'ai voulu recadré soit juste, ce n'est pas vraiment aux membres de faire ce genre de remontrances. Pour cela, il y a le bouton de signalement.

En ce qui me concerne, je n'ai pas de script qui permet de faire ça sous la main, mais avec ce que je t'ai donné, je pense que tu as toute la complexité de mise en place ;)

Re: ville aux alentours d'un point X

par bobmeers » 29 sept. 2009, 20:34

mon projet est en effet de cet ordre, je développe bénévolement pour une A.S.B.L. (association sans but lucratif) ,
je ne demande pas que l'on m'ecrive le script bien sur, mais il y a un tas de scripts qui traine sur le net pour tout et n'importe quoi, simplement si vous connaisez un truc du genre,l'url m'aiderait, ce que j'apelle "un truc tout cuit" je l'adapterez en fonction de mes besoin , faute de quoi je m'y atelle sans soucis, j'ai trouvez le script en JS , il traine sur le net a diverse adresse Mais je prefere traiter ce probleme cote serveur donc voila je cherche la meme chose mais en PHP
je ne voudrais froisser aucune suseptibilité, si mes propos peuvent etre interpreter autrement je vous presente mes excuses, le but n'est pas de faire faire le boulot à ma place, sans quoi j'aurais envoyer le cahier des charges du projet

Re: ville aux alentours d'un point X

par zeus » 29 sept. 2009, 19:22

Nous sommes là pour aider à developper et pas pour faire les codes tout pret.
A toi de te lancer avant tu as deja de bonnes pistes
voila de très bonnes pistes , on est loin du truc tout cuit en PHP, mais bon , il n'y a plus qu'a mijoter tout cela
je reste néamoins preneur d'un bon code source même à bidouillé un peu
ce point de mon site n'est pas vraiment encore prioritaire j'ai encore pas mal de formulaires à terminé avant, donc ce problème trouvera peut etre une solution dans les semaines qui suivent
avis à toutes les ames de bonnes volonté donc .
Un truc tout cuit on appel ca une "Prestation" et ca a un cout... sans vouloir être désagrable...

Bref, @+ et désolé pour le HS.
C'est bon, cette fois ci, on a compris ;)

Re: ville aux alentours d'un point X

par Dr@ke » 29 sept. 2009, 18:10

Sinon tu as la section: "Projets collaboratifs, entraide, bénévolat,... "

Re: ville aux alentours d'un point X

par FuZZyLine » 29 sept. 2009, 18:02

voila de très bonnes pistes , on est loin du truc tout cuit en PHP, mais bon , il n'y a plus qu'a mijoter tout cela
je reste néamoins preneur d'un bon code source même à bidouillé un peu
ce point de mon site n'est pas vraiment encore prioritaire j'ai encore pas mal de formulaires à terminé avant, donc ce problème trouvera peut etre une solution dans les semaines qui suivent
avis à toutes les ames de bonnes volonté donc .
Un truc tout cuit on appel ca une "Prestation" et ca a un cout... sans vouloir être désagrable...

Bref, @+ et désolé pour le HS.

Re: ville aux alentours d'un point X

par sylvaing26 » 29 sept. 2009, 17:47

Nous sommes là pour aider à developper et pas pour faire les codes tout pret.
A toi de te lancer avant tu as deja de bonnes pistes

Re: ville aux alentours d'un point X

par bobmeers » 29 sept. 2009, 17:37

voila de très bonnes pistes , on est loin du truc tout cuit en PHP, mais bon , il n'y a plus qu'a mijoter tout cela
je reste néamoins preneur d'un bon code source même à bidouillé un peu
ce point de mon site n'est pas vraiment encore prioritaire j'ai encore pas mal de formulaires à terminé avant, donc ce problème trouvera peut etre une solution dans les semaines qui suivent

avis à toutes les ames de bonnes volonté donc .

Re: ville aux alentours d'un point X

par zeus » 29 sept. 2009, 15:09

Très sincèrement, je doute qu'il faille prendre en compte le fait que la terre n'est pas plate. A moins de calculer la distance entre Singapour et Rio, je pense que l'on peut volontairement mettre de côté le relief.

Ceci dit, cela n'engage que moi ;)

Re: ville aux alentours d'un point X

par stopher » 29 sept. 2009, 14:54

Il faut d'abord projeter les coordonnées en surface plane ,

il y a de la doc la dessus sur le site de l'ign .

http://education.ign.fr/DISPLAY/000/527 ... ctions.pdf

Edit :

J'ai trouvé ceci sur un autre site , je cite :
1- mettre les angles en radian ( 1deg = Pi/180 rad )
2- considerer la terre comme une shère de rayon R ( 6'400 km environ )
3- les points sur terre répondent alors à x^2 + y^2 + z^2 = R^2 <0>

la latitue lat ( en radian ) donne

Z = R * sin (lat) <1>

ce qui implique une fois reporté dans <0>

X^2 + Y^2 = R^2*cos(lat)^2

compte tenu de la longiture long ( exprimée en rad ) il vient

X = R * cos(lat) * cos(long) et Y = R*cos(lat) * sin(long) <3>

1 & 3 donnent les coordonnées carartésiennes du point.

si 2 points sont proches on peut dire que la distance à parcourir pour aller de l'1 à l'autre est de distance entre les 2 points. Si non il faut aller de l'1 à l'autre en suivant l'arc de grand cercle ( cercle de centre le centre de la terre et qui passe par les 2 points en question ) et calculer sa longueur.

L = R * Theta ( Theta angle en rad <Point1, Centre terre, Point2> )
sin ( Theta ) = (Op1 vect Op2) / R^2 où Vect = produit vectoriel
O le centre de la terre Op1 et Op2 les 2 vecteurs.
Prendre les valeurs abolues si sin() < 0. S'assurer de prendre le + court des 2 arcs reliant P1 à P2. Choix corrects dans arcsin.



Sujet intéressant .

Good luck ,
Ch.

Re: ville aux alentours d'un point X

par zeus » 29 sept. 2009, 14:39

C'est assez simple en fait. Si tu dispose des coordonnées cartésiennes, tu as une hauteur et une largeur.
Prenons un exemple :
Image

Dans cet exemple, tu as 2 villes : A et B. Ces 2 villes disposes de coordonnées cartésiennes : A(3,5) et B(11,7).
Pour connaitre la distance entre les 2, il suffit de créer un triangle rectangle entre les 2 villes, puis de calculer la taille de l'hypoténuse (H) de ce triangle.

En effet, nous connaissons la taille de chaque côté de part et d'autre de l'angle droit (C1 et C2), en faisant la différence entre les coordonnées selon un axe :
C1 = 7-3 = 4 (la lattitude)
C2 = 11-5 = 6 (la longitude)

Et, en se basant sur le théorème de Pythagore, on sait que la taille de l'hypoténuse au carré et égale à la somme des 2 autres côtés au carrés. Rapporté au schéma, ce qui nous donne H² = C1² + C2², ou encore H = rac(C1² + C2²)

Dans notre exemple, en appliquant cette formule, on obtient :
H = rac(4² + 6²) = rac(52) = 7.2.
Du coup, on sais que la distance entre le point A et le point B est de 7.2.

Et, au final, à partir d'un calcul simple, tu peux savoir quelles sont les villes les plus proches d'un point donnés.

Re: ville aux alentours d'un point X

par sylvaing26 » 29 sept. 2009, 13:47

As tu de bonnes notions en géodesie et en PHP ?
Sinon cela risque d'etre très très dur en effet

Re: ville aux alentours d'un point X

par bobmeers » 29 sept. 2009, 13:36

hello
évidement c'est plus simple le rectangle
néanmoins pour trouver un vendeur à 10KM de chez moi le cercle et surtout le rayon reste le moyen le plus efficace
tes suggestions restent bien sur les bienvenues mais la question etait précises je pense
une suggestion pourrait aussi etre de simplement laisser tomber cette idée foireuse