IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[Processing] Calculs coordonnées Gps distance azimut


Sujet :

Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Retraité projets robotique
    Inscrit en
    Novembre 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité projets robotique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 26
    Points : 15
    Points
    15
    Par défaut [Processing] Calculs coordonnées Gps distance azimut
    Bonjour à tous,
    j'utilise la formule de calcul de coordonnées : https://www.dcode.fr/calcul-coordonnees-geographiques, au paragraphe: "Comment calculer un point d'arrivée à partir d'un point de départ ?" .
    J'ai retranscrit cette formule en Java et les coordonnées calculées m'indiquent un point différent de 50cm du calculateur en ligne, alors que les autres calculs de mon application sont précis au cm . Quelqu'un pourrait-il jeter un œil sur mon problème svp?
    Pour simplifier la recherche, une solution pour la première partie de la formule me permettrait de résoudre la deuxième partie semblable. Voici ma formule en Java sur Processing4.0: En connaissant le point de départ (ϕ1,λ1) (latitude, longitude), la direction θ (azimut depuis le nord) et la distance d sur une sphère de rayon R, j'ai calculé le trajet (calculs en radian) et trouvé les coordonnées d'arrivée (ϕ2,λ2)
    par la formule : l

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    lat = Math.asin(Math.sin(ϕ1)*Math.cos(distance/radius) +Math.cos(ϕ1)*Math.sin(distance/radius)*Math.cos(θ)) ;
    lat = lat*180/PI;
    lon = (λ1*PI/180) + Math.atan2(sin(θ*PI/180) * Math.sin(distance/radius) * cos(ϕ1*PI/180) , Math.cos(distance/radius) - Math.sin(ϕ1*PI/180) * Math.sin(lat*PI/180));
    lon=lon*180/PI;

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 887
    Points : 22 975
    Points
    22 975
    Billets dans le blog
    53
    Par défaut
    Apres correction de la formule, probablement car le site fait un arrondi en affichant ses resultats :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    package test.gpsdistance;
     
    import static java.lang.StrictMath.*;
     
    public final class Main {
        private static final double DEG_TO_RAD = PI / 180.;
        private static final double RAD_TO_DEG = 180 / PI;
     
        public static void main(final String... args) {
            final var gps = new LatLon(12.34, 56.78);
            final double directionDeg = 45;
            final double distanceKm = 1000;
            final double radiusKm = 6371;
     
            final var site = new LatLon(18.606373170899, 63.477594317657);
     
            double lat = asin(sin(gps.lat() * DEG_TO_RAD) * cos(distanceKm / radiusKm) + cos(gps.lat() * DEG_TO_RAD) * sin(distanceKm / radiusKm) * cos(directionDeg * DEG_TO_RAD));
            double lon = (gps.lon() * DEG_TO_RAD) + atan2(sin(directionDeg * DEG_TO_RAD) * sin(distanceKm / radiusKm) * cos(gps.lat() * DEG_TO_RAD),
                    cos(distanceKm / radiusKm) - sin(gps.lat() * DEG_TO_RAD) * sin(lat));
            lat = lat * RAD_TO_DEG;
            lon = lon * RAD_TO_DEG;
            System.out.printf("From (ϕ1,λ1) = %s, azimuth θ = %f°, distance d = %fKm -> (ϕ2,λ2) = %s%n", gps, directionDeg, distanceKm, new LatLon(lat, lon));
            System.out.printf("Was expecting (ϕ2,λ2) = %s%n", site);
        }
     
        public record LatLon(double lat, double lon) {
        }
    }
    Ce qui donne :

    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    From (ϕ11) = LatLon[lat=12.34, lon=56.78], azimuth θ = 45.000000°, distance d = 1000.000000Km -> (ϕ22) = LatLon[lat=18.606373170899314, lon=63.477594317656866]
    Was expecting (ϕ22) = LatLon[lat=18.606373170899, lon=63.477594317657]

    On a :

    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    J: 63.477594317656866
    S: 63.477594317657
     
    J: 18.606373170899314
    S: 18.606373170899
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre à l'essai
    Homme Profil pro
    Retraité projets robotique
    Inscrit en
    Novembre 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité projets robotique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Bonjour Bouye,
    Merci beaucoup pour tes explications et ta proposition de formule en Java. Je suis sur Processing4.0 pour raison d'IHM et la syntaxe est un peu différente, bien que basée sur java. Merci encore de bien vouloir m'accompagner. Concernant la précision des coordonnées calculées en ligne par Dcode, elles sont parfaites et je les ai validées par tracé géométrique, ce sont les formules que j'ai interprétées à partir de celles affichées sur le site Dcode qui ne donnent pas le bon résultat. Je vais tester à nouveau sur la base de ta réponse.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 887
    Points : 22 975
    Points
    22 975
    Billets dans le blog
    53
    Par défaut
    J'allais dire qu'il est possible que le calcul par le norme flottante habituelle (IEEE 754) ne soit pas assez precises mais le résultat est également different de ce qu'on obtient via C/C++ .
    Note par default le printf() de C fait un arrondi a la 6e décimale sur %f :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
     
    using namespace std;
     
    struct LatLon {
      double lat = 0;
      double lon = 0;
    };
     
    int main(int argc, char** argv) {
      const double PI = 3.141592653589793;
      const double DEG_TO_RAD = PI / 180.0;
      const double RAD_TO_DEG = 180 / PI;
     
      LatLon gps;
      gps.lat = 12.34;
      gps.lon = 56.78;
      const double directionDeg = 45;
      const double distanceKm = 1000;
      const double radiusKm = 6371;
     
      LatLon site;
      site.lat = 18.606373170899;
      site.lon = 63.477594317657;
     
      double lat = asin(sin(gps.lat * DEG_TO_RAD) * cos(distanceKm / radiusKm) + cos(gps.lat * DEG_TO_RAD) * sin(distanceKm / radiusKm) * cos(directionDeg * DEG_TO_RAD));
      double lon = (gps.lon * DEG_TO_RAD) + atan2(sin(directionDeg * DEG_TO_RAD) * sin(distanceKm / radiusKm) * cos(gps.lat * DEG_TO_RAD),
    						cos(distanceKm / radiusKm) - sin(gps.lat * DEG_TO_RAD) * sin(lat));
      lat = lat * RAD_TO_DEG;
      lon = lon * RAD_TO_DEG;
      LatLon res;
      res.lat = lat;
      res.lon = lon;
     
      printf("From (ϕ1,λ1) = ( %f, %f), azimuth θ = %f°, distance d = %fKm -> (ϕ2,λ2) = ( %f, %f)\n", gps.lat, gps.lon, directionDeg, distanceKm, lat, lon);
      printf("Was expecting (ϕ2,λ2) = ( %f, %f)\n", site.lat, site.lon);
     
      printf("\n");
     
      printf("From (ϕ1,λ1) = ( %.20f, %.20f), azimuth θ = %f°, distance d = %fKm -> (ϕ2,λ2) = ( %.20f, %.20f)\n", gps.lat, gps.lon, directionDeg, distanceKm, lat, lon);
      printf("Was expecting (ϕ2,λ2) = ( %.20f, %.20f)\n", site.lat, site.lon);
     
      return EXIT_SUCCESS;
    }
    Ce qui donne:

    Code Console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    From (ϕ11) = ( 12.340000, 56.780000), azimuth θ = 45.000000°, distance d = 1000.000000Km -> (ϕ22) = ( 18.606373, 63.477594)
    Was expecting (ϕ22) = ( 18.606373, 63.477594)
     
    From (ϕ11) = ( 12.33999999999999985789, 56.78000000000000113687), azimuth θ = 45.000000°, distance d = 1000.000000Km -> (ϕ22) = ( 18.60637317089931386249, 63.47759431765686599647)
    Was expecting (ϕ22) = ( 18.60637317089900122369, 63.47759431765700099959)

    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    J:   63.477594317656866
    S:   63.477594317657
    C:   63.477594
    C20: 63.47759431765700099959
     
    J:   18.606373170899314
    S:   18.606373170899
    C:   18.606373
    C20: 18.60637317089900122369

    * Ici C20 = C en imprimant 20 décimales.

    Après il y a peut-être des differences aussi dans l’implémentation des fonctions trigonométriques. As-tu essaye la definition du site pour la fonction atan2() ?

    Et sinon il faudrait comparer le nombre binaire pour savoir si les résultats sont vraiment différents. En Java c'est du big endian, et on obtient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(lat)));
    System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(lon)));
    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    100000000110010100110110011101101000101101010100010111100110011
    100000001001111101111010010000111001111100000111000101110111100

    Pas vraiment sur de savoir comment faire en C/C++ sans écrire dans un fichier binaire, d'autant plus que je risque de choper un résultat en little endian vu que je suis sur un PC.


    EDIT - Ah oui et en essayant avec BigDecimal ? Par contre il va falloir utiliser des libs externes pour la trigonométrie...
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre à l'essai
    Homme Profil pro
    Retraité projets robotique
    Inscrit en
    Novembre 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité projets robotique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par bouye Voir le message
    J'allais dire qu'il est possible que le calcul par le norme flottante habituelle (IEEE 754) ne soit pas assez precises mais le résultat est également different de ce qu'on obtient via C/C++ .
    Note par default le printf() de C fait un arrondi a la 6e décimale sur %f :
    [CODE]#include <cstdlib>...
    J'avance grâce à vos infos et maintenant la valeur numérique de la latitude issue d’une fichier.csv devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double φ1 =(Double.parseDouble(table.getString(iLignecalcullatlonBearing, "LAT")));
    et le calcul de lat: final double lat=(Math.asin(Math.sin(φ1* Math.PI/ 180.0d)*Math.cos(distance_D /6_371_000d)  
    +Math.cos(φ1* Math.PI / 180.0d)*Math.sin(distance_D /6_371_000d)*Math.cos(θ* Math.PI / 180.0d)   )) 
    *180.0d/Math.PI ;
    A tester maintenant.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Retraité projets robotique
    Inscrit en
    Novembre 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité projets robotique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Encore une fois merci, la précision est maintenant millimétrique!
    A bientôt sur ce précieux forum.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convertir des coordonnes gps utm en decimal
    Par samy01 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 24/01/2019, 09h37
  2. Transformer déplacement xy en coordonnés GPS
    Par Nicolasdiego dans le forum Excel
    Réponses: 1
    Dernier message: 03/08/2016, 13h05
  3. [WD15] Calcul de la distance et de l'azimut entre 2 positions Gps
    Par dakota77 dans le forum WinDev
    Réponses: 2
    Dernier message: 01/11/2010, 16h47
  4. Réponses: 6
    Dernier message: 26/03/2009, 11h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo