Skip to content

Améliorer l'algorithme de calcul des vitesses

h3. Description

Peux-tu nous dire quel principe est utilisé pour calculer la distance entre 2 coordonnées ?

En effet, en me basant sur la 3.1.2 (c'est vrai aussi sur la 3.1.1) j'ai fait le calcul manuellement pour 2 activités que le logiciel marque en erreur de vitesse (et j'ai confirmé le résultat avec un site web de conversion http://www.lexilogos.com/calcul_distances.htm) : je constate que ton algo surestime les vitesses.

Soit la route du 14/07, activités de 6h20 et 6h25, dans la base que je t'enverrai séparément :

6h00 : (LAT,LON) = (4°00' S, 46°32 E) 6h20 : (LAT,LON) = (3°58 S, 46°58' E)

Sachant que 1' à la surface de la Terre == 1 mille parcouru :

Calcul de la distance en Y (d) : d == 46°58' - 46°32' = 0°26' == 26 milles

Calcul de la distance en Y (D) : D == 4°00' - 3°58' = 0°02' == 2 milles

Pour avoir la distance entre les 2 points => Pythagore => sqrt(26² + 2²) = 26 milles

Soit 26 milles en 20 minutes Soit 26*3 =78 milles/heure = 78 nœuds

Or ton algo donne 89 nœuds

Dans ce cas, 78 ou 89 nœuds, la vitesse reste supérieure mais dans des cas plus limite ça pose problème.

Pourrais-tu vérifier cet algo en ce sens ?

h3. Solution actuellement utilisée

Le calcul de la distance entre deux points est celle-ci :

    public static final double EARTH_RADIUS = 3958.75;

    /** le rayon de la terre en kilomètres */
    public static final int R = 6378;

 /**
     * Calcule la distance entre deux points (en miles nautique).
     * 

* Il s'agit d'une approxiation utilisant la méthode d'orthodromie. *

* http://fr.wikipedia.org/wiki/Orthodromie *

* d = R * arccos(cos(lat1) * cos(lat2) *cos(long2 - long1) + sin(lat1) * *sin(lat2)) * * @param p0 le premier point * @param p1 le second point * @return la distance calculée entre les deux points en noeud. */ public static double getDistanceInMile(GPSPoint p0, GPSPoint p1) { double d; if (p0.isSameLocation(p1)) { // same location : so distance is null for sure // We use this limit case, otherwise in next computation, tmp // value can be more than 1 (1.00000000002) and Math.acos(tmp) // then is NaN d = 0d; } else { double lat1 = p0.getLatitude(); double lng1 = p0.getLongitude(); double lat2 = p1.getLatitude(); double lng2 = p1.getLongitude(); double dLat = Math.toRadians(lat2 - lat1); double dLng = Math.toRadians(lng2 - lng1); double sindLat = Math.sin(dLat / 2); double sindLng = Math.sin(dLng / 2); double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2) * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); d = EARTH_RADIUS * c; } return d; }

Si cela ne convient pas, merci de me fournir l'algorithme exacte à utiliser. merci

(from redmine issue 6242 created on 2014-12-04, closed on 2016-09-21)