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)