Avr
08
|
Après avoir réussi à modifier mes coordonnées dans Google Latitude, j’ai eu envie de voir comment on pouvait optimiser un trajet entre plusieurs points…
Le problème me semblait complexe, mais je n’imaginais pas encore à quel point
Heureusement, j’ai très rapidement trouvé de la documentation concernant ce classique problème, plus communément appelé : problème du voyageur de commerceW.
J’ai également trouvé un projet déjà écrit en Delphi qui m’a permis de l’implémenter sans finalement, vraiment comprendre tout ce qui se passait… les algorithmes génétiques n’étant clairement pas ma tasse de café…. Vous pouvez visiter le site Web de l’auteur sur cette page.
L’application que j’ai faite me permet de charger un fichier KMLW, généré avec Google Earth ayant la structure suivante :
- Un répertoire qui contient :
- des repères
Je charge alors le fichier KML en récupérant le nom, les coordonnées GPS et l’altitude de chaque repère dans une liste (l’altitude n’est pas utilisée pour le calcul des distances).
Je calcule ensuite les distances entre chaque position. Chaque distance correspond à l’écart entre la ligne qui l’affiche et la position précédente. La première ligne est calculé en utilisant la dernière position.
Ce calcul est effectué en prenant une valeur constante pour le rayon équatorial :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | function CalculateDistance(dFromLatitude, dFromLongitude, dToLatitude, dToLongitude: Double): Double; const EARTH_RADIUS = 6378; // Rayon équatorial : 6 378,137 function ArcCosWithZero(dValue: Double): Double; var dCheck: Double; begin dCheck := sqrt(-dValue*dValue+1); if (dCheck = 0) then dCheck := 0.0000000001; Result := -ArcTan(dValue / dCheck) + (Pi / 2); end; begin // Degrés en radians dFromLatitude := dFromLatitude / 180 * Pi; dFromLongitude := dFromLongitude / 180 * Pi; dToLatitude := dToLatitude / 180 * Pi; dToLongitude := dToLongitude / 180 * Pi; //Distance = Rayon * | arccos[ sin(LatA).sin(LatB)+cos(LatA).cos(LatB).cos(LonA-LonB) ] | // Rayon équatorial : 6 378,137 Result := EARTH_RADIUS * ArcCosWithZero(Sin(dFromLatitude)*Sin(dToLatitude)+Cos(dFromLatitude)*Cos(dToLatitude)*Cos(dFromLongitude - dToLongitude)); end; |
Ensuite, grâce à l’algorithme et au code source de l’application de Troels, j’optimise les distances entre les différents repères :
Pour finalement réafficher la liste dans l’ordre trouvé :
Si cette application vous intéresse, vous pouvez la télécharger depuis ce lien. Vous pouvez également trouver un exemple du type de fichier KML attendu par l’application.
Cette application est développée avec Embarcadero Delphi XE.
@ Juju : j’ai ajouté une case à cocher pour ne plus permuter la première position. Etant donné l’algorithme utilisé, c’est ce que je peux faire de mieux… sinon, il faudrait tout recasser/repenser…
(arrow) Mise à jour : Version 1.4.6
(arrow) Mise à jour : Version 1.4.7
@ Juju : Pour votre trajet Toulouse-Paris (sans tenir compte des villes/régions intermédiaires…), je procéderais ainsi :
En admettant que le meilleur chemin a été trouvé… il en existe 2 possibles pour un même point de départ….
Par exemple, on peut avoir :
Du coup, si les chemins ne se chevauchent pas…
Pour les avoir dans le même ordre, sur l’une des deux sauvegardes, je clique sur le bouton Inverser puis sur le bouton Décaler vers le bas…
Ensuite, on peut sauvegarder et recharger les deux fichiers…
J’espère que cette méthode vous apportera une solution adéquate
(arrow) Mise à jour : Version 1.4.8
(arrow) Mise à jour : Version 1.4.9
(arrow) Mise à jour : Version 1.4.10
Super merci pour ton boulot ça m’aide de plus en plus !!!
@ Juju :
(arrow) Mise à jour : Version 1.4.11
(arrow) Mise à jour : Version 1.4.12
(arrow) Mise à jour : Version 2.0.0
modifié/traduit par Whiler
Politique de confidentialité