Tri coordonnées gps
nicdu40
Messages postés
25
Date d'inscription
Statut
Membre
Dernière intervention
-
-
-
Bonjour,
j'ai un tableau comme suit:
azert;brazil;-14.235004;-51.92528
azerty;bordeaux;44.837789;-0.57918
toto;liboune;44.912998;-0.243985
nom;paris;48.856614;2.3522219
tata;marseille;43.296482;5.36978
kiki;nice;43.7101728;7.2619532
j'ai donc le nom;adresse;latitude;longitude ,
j'arrive a trier sans problème individuellement, par contre comment m'y prendre pour pour faire un trie en fonction des distances entre chaque adresse?
je débute en perl , une piste serait la bien venue, Merci
j'ai un tableau comme suit:
azert;brazil;-14.235004;-51.92528
azerty;bordeaux;44.837789;-0.57918
toto;liboune;44.912998;-0.243985
nom;paris;48.856614;2.3522219
tata;marseille;43.296482;5.36978
kiki;nice;43.7101728;7.2619532
j'ai donc le nom;adresse;latitude;longitude ,
j'arrive a trier sans problème individuellement, par contre comment m'y prendre pour pour faire un trie en fonction des distances entre chaque adresse?
je débute en perl , une piste serait la bien venue, Merci
A voir également:
- Tri coordonnées gps
- Coordonnées gps - Guide
- Gps sans internet - Guide
- Comment faire un tri personnalisé sur excel - Guide
- Logiciel tri photo - Guide
- Gps - Accueil - Transports & Cartes
5 réponses
Bonsoir, à cette adresse une source récente pour le calcul de distance suivant la méthode sphérique.
https://codes-sources.commentcamarche.net/source/100762-classe-gps-calcul-distance
Cette méthode donne des résultats approximatifs.
Si tu veux plus précis recherche "loxodromie" sur les sites de l'IGN.
--
https://codes-sources.commentcamarche.net/source/100762-classe-gps-calcul-distance
Cette méthode donne des résultats approximatifs.
Si tu veux plus précis recherche "loxodromie" sur les sites de l'IGN.
--
oui merci pour les distances pas de soucis:
my $pi = 3.14159265358979;
sub deg_to_rad { ($_[0]/180) * $pi }
sub rad_to_deg { ($_[0]/$pi) * 180 }
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
sub tan { sin($_[0]) / cos($_[0]) }
sub atan { atan2($_[0],1) };
my $lat_a = $lat;
my $lon_a = $lng;
my $aa = $pi / 180;
my $lat1 = $lat_a * $aa;
my $lat2 = $lat_b * $aa;
my $lon1 = $lon_a * $aa;
my $lon2 = $lon_b * $aa;
my $t1 = sin($lat1) * sin($lat2);
my $t2 = cos($lat1) * cos($lat2);
my $t3 = cos($lon1 - $lon2);
my $t4 = $t2 * $t3;
my $t5 = $t1 + $t4;
my $rad_dist = atan(-t5/sqrt(-$t5 * $t5 +1)) + 2 * atan(1);
my $dist = ($rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446;
ce que je cherche c'est comment calculer la distance entre chaque ville pour me retrouver avec un tri a partir d'une ville de départ: exemple:
A la base j'ai:
azert;brazil;-14.235004;-51.92528
azerty;bordeaux;44.837789;-0.57918
toto;liboune;44.912998;-0.243985
nom;paris;48.856614;2.3522219
tata;marseille;43.296482;5.36978
kiki;nice;43.7101728;7.2619532
Si je part de nice,
ça me donnerait:
kiki;nice;43.7101728;7.2619532
tata;marseille;43.296482;5.36978
toto;liboune;44.912998;-0.243985
azerty;bordeaux;44.837789;-0.57918
nom;paris;48.856614;2.3522219
azert;brazil;-14.235004;-51.92528
en fait je pense qu'il faudrait calculer tous les km entre chaque ville a partir de nice, en calculant toutes les combinaisons, et en ne gardant que celle ou il y a le moins de distance.
my $pi = 3.14159265358979;
sub deg_to_rad { ($_[0]/180) * $pi }
sub rad_to_deg { ($_[0]/$pi) * 180 }
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
sub tan { sin($_[0]) / cos($_[0]) }
sub atan { atan2($_[0],1) };
my $lat_a = $lat;
my $lon_a = $lng;
my $aa = $pi / 180;
my $lat1 = $lat_a * $aa;
my $lat2 = $lat_b * $aa;
my $lon1 = $lon_a * $aa;
my $lon2 = $lon_b * $aa;
my $t1 = sin($lat1) * sin($lat2);
my $t2 = cos($lat1) * cos($lat2);
my $t3 = cos($lon1 - $lon2);
my $t4 = $t2 * $t3;
my $t5 = $t1 + $t4;
my $rad_dist = atan(-t5/sqrt(-$t5 * $t5 +1)) + 2 * atan(1);
my $dist = ($rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446;
ce que je cherche c'est comment calculer la distance entre chaque ville pour me retrouver avec un tri a partir d'une ville de départ: exemple:
A la base j'ai:
azert;brazil;-14.235004;-51.92528
azerty;bordeaux;44.837789;-0.57918
toto;liboune;44.912998;-0.243985
nom;paris;48.856614;2.3522219
tata;marseille;43.296482;5.36978
kiki;nice;43.7101728;7.2619532
Si je part de nice,
ça me donnerait:
kiki;nice;43.7101728;7.2619532
tata;marseille;43.296482;5.36978
toto;liboune;44.912998;-0.243985
azerty;bordeaux;44.837789;-0.57918
nom;paris;48.856614;2.3522219
azert;brazil;-14.235004;-51.92528
en fait je pense qu'il faudrait calculer tous les km entre chaque ville a partir de nice, en calculant toutes les combinaisons, et en ne gardant que celle ou il y a le moins de distance.
#!/usr/local/bin/perl use POSIX qw(strftime); use Math::Complex; #use strict; #use warnings; use DBI; use LWP::Simple; # from CPAN use JSON qw( decode_json ); # from CPAN #récupère l'entrée standard dans la variable $in read(STDIN, $in, $ENV{CONTENT_LENGTH}); # la chaine $in est coupée suivant le caractère & et crée la liste @champs @champs = split(/&/,$in); # traitement de chaque élément $e de la liste @champs foreach $e (@champs) { # dissocie chaque élément, de la forme nom=valeur en une paire de variable (nom,valeur) ($nom, $valeur) = split(/=/,$e); # transforme tous les caractères saisis en minuscules $valeur =~ tr/A-Z/a-z/; # crée à partir du tableau @champs une liste associative %champs $champs{$nom}=$valeur; } my $format = "json"; #can also to 'xml' my $geocodeapi = "[https://maps.googleapis.com/maps/api/geocode/]"; # génére l'en-tête du document HTML renvoyé print("Content-Type: text/html\n\n"); # puis le document HTML print <<"SORTIE"; <HEAD><TITLE> Réponse </TITLE></HEAD> <BODY> <H2 ALIGN=CENTER>RESULTAT</H2> <CENTER><TABLE BORDER><TR> <TH>Nom du champ <TH>Valeur</TR> SORTIE my $adresse; my $NOM; my $lat; my $lng; # le traitement est ici réduit à afficher les valeurs transmises while (($nom, $valeur) = each(%champs)) { if ($nom =~ /adresse/){ $valeur =~ s/\%2c\+/-/g; $valeur =~ s/\+/\ /g; $adresse = $valeur; my $url = $geocodeapi . $format . "?address=" . $adresse . "&sensor=false" ; my $json = get($url); my $d_json = decode_json( $json ); $lat = $d_json->{results}->[0]->{geometry}->{location}->{lat}; $lng = $d_json->{results}->[0]->{geometry}->{location}->{lng}; } if ($nom =~ /nom/){ $NOM = $valeur; } print "<TR><Td>$nom = </td><Td>$valeur</td></TR>"; } ############### open (FH, ">>test-perl"); print FH "$NOM;$adresse;$lat;$lng\n"; close(FH); ############## open(FH, "test-perl") or die "!"; # Copie du contenu du fichier dans un tableau my @table=<FH>; # Afficher la taille du tableau print scalar(@table)."\n"; print "<BR\>"; close(FH); my $pi = 3.14159265358979; sub atan { atan2($_[0],1) }; my $aa = $pi / 180; my $local_lat = 43.637844; my $local_long = -1.420939; my $lat_a = $local_lat; my $lon_a = $local_long; my $lat1 = $lat_a * $aa; my $lon1 = $lon_a * $aa; foreach $line (@table) { ($nom, $adresse, $lat, $lng, $dist) = split(";", $line); my $lat_b = $lat; my $lon_b = $lng; my $lat2 = $lat_b * $aa; my $lon2 = $lon_b * $aa; my $t1 = sin($lat1) * sin($lat2); my $t2 = cos($lat1) * cos($lat2); my $t3 = cos($lon1 - $lon2); my $t4 = $t2 * $t3; my $t5 = $t1 + $t4; my $rad_dist = atan(-$t5/sqrt(-$t5 * $t5 +1)) + 2 * atan(1); my $dist = ($rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446; $line = $line . ";" . $dist; } @out = sort { (split ';', $a )[4] <=> #cmp (split ';', $b )[4] } @table; foreach $line (@out) { ($nom, $adresse, $lat, $lng, $dist) = split(";", $line); print "<TR><Td>$nom</td><Td>$adresse</td><Td>$lat</td><Td>$lng</td><Td>$dist</td></TR>"; }
ce qui me donne:
nom ville lat long km
bobo orx 43.602883 -1.372563 5.49883038421565
nico seignosse 43.692694 -1.384908 6.74821123208138
rhune ascain 43.345172 -1.621327 36.3135240698413
bobo pau 43.2951 -0.370797 92.8625864850123
azert marseille 43.296482 5.36978 548.822503921505
bbb brazil -14.235004 -51.92528 8217.52868892235
nom mexico 23.634501 -102.552784 9051.01695660936
nom mexico 23.634501 -102.552784 9051.01695660936
nom mexico 23.634501 -102.552784 9051.01695660936
nom mexico 23.634501 -102.552784 9051.01695660936
bobo tokio 35.6894875 139.6917064 10350.9145027704
le départ se fait à partir d'une seulle ville : my $local_lat = 43.637844; my $local_long = -1.420939;
ça calcul les distances à partir de ce point, mais ce n'est pas ce que je voudrai
j'avance un peu , mais je n'est pas encore la bonne methode.....
EDIT: Ajout de la coloration syntaxique.
bon voila , pour ceux qui sont intéressé: ça calcul la ville la plus proche du point de départ, puis ensuite depuis l'autre ville , ainsi de suite,
c'est pour optimiser les tournées de RDV , .... ,
Bon j'ai du faire des erreurs, je n'ai jamais suivi de cours , soyez indulgent ;-)
c'est pour optimiser les tournées de RDV , .... ,
Bon j'ai du faire des erreurs, je n'ai jamais suivi de cours , soyez indulgent ;-)
############## #adresse de départ my $local_lat = 43.637844; my $local_long = -1.420939; my $lat_a = $local_lat; my $lon_a = $local_long; my $pi = 3.14159265358979; sub atan { atan2($_[0],1) }; my $aa = $pi / 180; open(FH, "test-perl") or die "!"; # Copie du contenu du fichier dans un tableau my @tabl=<FH>; my $nb_lignes = scalar(@tabl); # Afficher la taille du tableau print "NB lignes = $nb_lignes \n"; #print "<BR\>"; close(FH); #my $lat1 = $lat_a * $aa; #my $lon1 = $lon_a * $aa; my $line; #boucle while ($nb_lignes > 0) { foreach $line (@tabl) { my ($nom, $adresse, $lat, $lng) = split("\ ", $line); $line = join(' ',$nom,$adresse,$lat,$lng); my $lat_b = $lat; my $lat1 = $lat_a * $aa; my $lon1 = $lon_a * $aa; my $lon_b = $lng; my $lat2 = $lat_b * $aa; my $lon2 = $lon_b * $aa; my $t1 = sin($lat1) * sin($lat2); my $t2 = cos($lat1) * cos($lat2); my $t3 = cos($lon1 - $lon2); my $t4 = $t2 * $t3; my $t5 = $t1 + $t4; my $dista; if (($lat_a == $lat_b)&&($lon_a == $lon_b)) { $dista = 0 ; }else{ my $rad_dist = atan(-$t5/sqrt(-$t5 * $t5 +1)) + 2 * atan(1); $dista = ($rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446; } $line =~ s/\n//g; $line = $line . " " . $dista ; } @out = sort { (split ' ' , $a )[4] <=> (split ' ' , $b )[4] } @tabl; my $proche = shift(@out); #print "plus proche= $proche\n"; my @col = split( ' ' , $proche); $lat_a = $col[2]; $lon_a = $col[3]; $nb_lignes -=1; @tabl = @out ; #print "\n"; my ($nom, $adresse, $lat, $lng, $dista) = split("\ ", $proche); print "<TR><Td>$nom</td><Td>$adresse</td><Td>$lat</td><Td>$lng</td><Td>$dista</td></TR>"; }
Salut nicdu40,
Plutôt que de calculer la distance à vol d'oiseau, tu pourrais utiliser une API pour calculer la distance par la route et le temps de trajet. Google a cela :
https://developers.google.com/maps/documentation/javascript/distancematrix
https://developers.google.com/maps/documentation/distance-matrix/start
qui te permet d'obtenir une matrice de distances et temps de parcours entre un ou plusieurs points de départ et un ou plusieurs points d'arrivée.
Par exemple :
donne :
Tu peux ensuite faire tes tris, en fonction de ta ville de départ.
Dal
Plutôt que de calculer la distance à vol d'oiseau, tu pourrais utiliser une API pour calculer la distance par la route et le temps de trajet. Google a cela :
https://developers.google.com/maps/documentation/javascript/distancematrix
https://developers.google.com/maps/documentation/distance-matrix/start
qui te permet d'obtenir une matrice de distances et temps de parcours entre un ou plusieurs points de départ et un ou plusieurs points d'arrivée.
Par exemple :
#!/usr/bin/perl use strict; use warnings; use LWP::Simple; use JSON qw( decode_json ); use Data::Dumper; my $origins = "&origins=Paris+France|Bordeaux+France|Lyon+France|Marseille+France"; my $destinations = "&destinations=Paris+France|Bordeaux+France|Lyon+France|Marseille+France"; my $content = get("https://maps.googleapis.com/maps/api/distancematrix/json?" . $origins . $destinations); die "Couldn't get it!" unless defined $content; my $data = decode_json($content); my @rows = @{ $data->{'rows'} }; foreach my $r (@rows) { my @elements = @{ $r->{'elements'} }; foreach my $d (@elements) { print $d->{'duration'}{'value'} . "\t\t"; } print "\n"; }
donne :
0 20925 15491 26226
21151 0 18954 21478
15956 19102 0 11233
26751 21713 11269 0
Tu peux ensuite faire tes tris, en fonction de ta ville de départ.
Dal
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
salut, merci Dal,
faut que j'aille voir ça.
merci à tous les autres dailleur .
de mon coté j'ai réussi a faire ce que je voulais au départ, mais c'est vrais que c'est a vol d'oiseau, c'est bon pour les avions quoi....
en fait j'ai fais tout grace a la permutation "Fischer-Krause ordered permutation generator"
ça m'a ouvert les yeux...
maintenant je vais faire la même avec les conseils de dal.
bon du coup voila, calcul du meilleur itinéraire pour les objets volants:
le fichier test-perl doit être écrit ainsi:
nico hossegor 43.6646192 -1.3976871
lolo orx 43.602883 -1.372563
pipo seignosse 43.69269 -1.384
coco tarnos 43.5408 -1.461038
gaga dax 43.708608 -1.051945
faut que j'aille voir ça.
merci à tous les autres dailleur .
de mon coté j'ai réussi a faire ce que je voulais au départ, mais c'est vrais que c'est a vol d'oiseau, c'est bon pour les avions quoi....
en fait j'ai fais tout grace a la permutation "Fischer-Krause ordered permutation generator"
ça m'a ouvert les yeux...
maintenant je vais faire la même avec les conseils de dal.
bon du coup voila, calcul du meilleur itinéraire pour les objets volants:
le fichier test-perl doit être écrit ainsi:
nico hossegor 43.6646192 -1.3976871
lolo orx 43.602883 -1.372563
pipo seignosse 43.69269 -1.384
coco tarnos 43.5408 -1.461038
gaga dax 43.708608 -1.051945
############## #adresse de départ my $local_lat = 43.6305177; my $local_long = -1.3927591; my $addr = "magazin"; my $lat_a = $local_lat; my $lon_a = $local_long; my $total = 0; my $pi = 3.14159265358979; my $pii = $pi / 180; open(FH, "test-perl") or die "!"; # Copie du contenu du fichier dans un tableau my @tabl=<FH>; my $nb_lignes = scalar(@tabl); # Afficher la taille du tableau print "NB lignes = $nb_lignes \n"; #print "<BR\>"; close(FH); #calcul des distances sub distanceA_B { my ($lat_A,$lat_B,$lon_A,$lon_B) = @_; my $lat_a = $lat_A; my $lat_b = $lat_B; my $lon_a = $lon_A; my $lon_b = $lon_B; my $lat1 = $lat_a * $pii; my $lon1 = $lon_a * $pii; my $lat2 = $lat_b * $pii; my $lon2 = $lon_b * $pii; my $t1 = sin($lat1) * sin($lat2); my $t2 = cos($lat1) * cos($lat2); my $t3 = cos($lon1 - $lon2); my $t4 = $t2 * $t3; my $t5 = $t1 + $t4; my $dista; if (($lat_a == $lat_b)&&($lon_a == $lon_b)) { $dista = 0 ; }else{ my $rad_dist = atan(-$t5/sqrt(-$t5 * $t5 +1)) + 2 * atan(1); $dista = ($rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446; } return ($dista); } ######################################################################################################" foreach my $ligne (@tabl) { my ($nom, $adresse, $lat, $lng) = split("\ ", $ligne); $ligne = join('_',$nom,$adresse,$lat,$lng); } ###permutation :-) sub permute (&@) { my $code = shift; my @idx = 0..$#_; while ( $code->(@_[@idx]) ) { my $p = $#idx; --$p while $idx[$p-1] > $idx[$p]; my $q = $p or return; push @idx, reverse splice @idx, $p; ++$q while $idx[$p-1] > $idx[$q]; @idx[$p-1,$q]=@idx[$q,$p-1]; } } my @a; permute { push @a, "@_" } @tabl; foreach my $aa (@a) { ### on remet les coordonnées de départ avant chaque tour de @a $lat_a = $local_lat; $lon_a = $local_long; my @array = split(' ',$aa); foreach my $array (@array) { $array =~ s/\n//g; my ($nom, $adresse, $lat, $lng) = split("_", $array); if ($addr eq $adresse) { $dista = 0; } else{ ($dista) = distanceA_B ($lat_a,$lat,$lon_a,$lng); } # $array = $array . " " . $dista ; #print $array . "\n"; $total += $dista ; ### a chaque tour de @array le point gps precedant devient le départ. $lat_a = $lat; $lon_a = $lng; } #print "total distance= $total \n"; $aa = $aa . " " . $total ; #print $aa . "\n"; $total=0; } ###numero de colone oû se trouve le total de chaque possibilité = nb de villes a calculer (+1) my $col_tot = $nb_lignes ; ###calcul du meilleur total @out = sort { (split ' ' , $a )[$col_tot] <=> (split ' ' , $b )[$col_tot] } @a; #recupere la 1er ligne my $proche = shift(@out); print $proche . "\n"; @tableau_web = split(' ',$proche); #recupere le nombre de km: my $total_dist = pop(@tableau_web); ##inscription dans un tableau le meilleur parcour ! foreach my $ligne_web (@tableau_web) { my ($nom, $adresse, $lat, $lng) = split("_", $ligne_web); print "<TR><Td>$nom</td><Td>$adresse</td><Td>$lat</td><Td>$lng</td></TR>"; print "\n"; } print "<TR><Td>distance-totale=</td><Td>$total_dist</td></TR>";
A+