web-dev-qa-db-fra.com

calculer la distance réelle parcourue par mobile

Je souhaite calculer la distance réelle parcourue par mobile (iOS et Android). Je sais que grâce à l'API Google Map, nous pouvons trouver la distance optimale entre 2 coordonnées. Mais je veux calculer la distance, le chemin réel parcouru par le mobile (dans le véhicule).

Un Algo que j'ai appris enregistre les coordonnées après x secondes, disons après 5 ou 10 secondes, puis calcule la distance entre les coordonnées consécutives, et la somme donnera la distance totale.

Je veux discuter d'une meilleure approche de sa solution, Y a-t-il une meilleure solution?

Edit: Comment fonctionnent les applications comme l'application Nike et Uber?

35
Haris

------------------ [~ # ~] mise à jour [~ # ~] --- -------------------

Il y a deux points principaux dans votre question.

1) Obtenez les coordonnées téléphoniques (qui ont été traitées dans la première partie de cette réponse)

2) Calculez la distance réelle entre ces deux coordonnées

À mon humble avis, le calcul pourrait être effectué par un service Web: un calcul basé uniquement sur la distance entre deux coordonnées peut conduire à un résultat vraiment faux.

Voici un exemple d'un tel service Web https://graphhopper.com/#directions-api

L'application de démonstration: https://graphhopper.com/api/1/examples/

Il est basé sur le flux de trafic (comme beaucoup de ces outils). Vous devez donc faire attention à l'ordre des coordonnées car cela peut entraîner un résultat erroné.

Par exemple avec deux points dans le bon ordre: enter image description here

Cela donne un bon résultat

Mais si vous donnez un mauvais ordre (avec les mêmes coordonnées) enter image description here

Pour les mêmes coordonnées, cela peut conduire à un résultat extrêmement différent.

Donc, pour les coordonnées ABCD (dans l'ordre chromatique), vous devez faire:

A-> B B-> C C-> D

Graphhopper semble capable de faire un calcul de distance hors ligne

Voici la lib sur iOS et Android

https://github.com/graphhopper/graphhopper-ios/

https://github.com/graphhopper/graphhopper/tree/master/Android

----------------------------------------- ----------

Vous devez définir le fonctionnement de votre application. Premier plan ou arrière-plan?

Comme indiqué dans d'autres réponses, vous devrez obtenir la position de l'utilisateur toutes les X secondes. Calculez ensuite la distance.

Pour iOS:

  1. Vous pouvez utiliser les informations de ce site Web: http://mobileoop.com/

Il parle de suivre l'emplacement des utilisateurs sur iOS lorsque l'application est en arrière-plan.

  1. Voici le github: https://github.com/voyage11/Location

Ensuite, vous devez convertir le point grâce à

CLLocationDistance distance = [aCLLocationA distanceFromLocation:aCLLocationB];

Vous pouvez également vérifier cela (depuis Apple doc) https://developer.Apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html :

Assurez-vous que la propriété pausesLocationUpdatesAutomatically du gestionnaire d'emplacement est définie sur YES. Lorsque cette propriété est définie sur YES, Core Location interrompt les mises à jour d'emplacement (et met le matériel de localisation hors tension) chaque fois qu'il est logique de le faire, par exemple lorsque l'utilisateur est peu susceptible de se déplacer de toute façon. (Core Location suspend également les mises à jour lorsqu'il ne peut pas obtenir de correction d'emplacement.)

Attribuez une valeur appropriée à la propriété activityType du gestionnaire d'emplacements. La valeur de cette propriété aide le gestionnaire d'emplacement à déterminer quand il est sûr de suspendre les mises à jour d'emplacement. Pour une application qui fournit une navigation automobile détaillée, la définition de la propriété sur CLActivityTypeAutomotiveNavigation oblige le gestionnaire d'emplacement à suspendre les événements uniquement lorsque l'utilisateur ne se déplace pas sur une distance significative sur une période de temps.

CLActivityTypeAutomotiveNavigation vous assure d'obtenir une position sur une route.

Pour Android:

  1. Vous pouvez utiliser ce projet: https://github.com/quentin7b/Android-location-tracker

Cela peut facilement vous aider à obtenir la position de l'utilisateur dans le temps grâce à l'objet TrackerSettings

TrackerSettings settings =
        new TrackerSettings()
            .setUseGPS(true)
            .setUseNetwork(true)
            .setUsePassive(true)
            .setTimeBetweenUpdates(30 * 60 * 1000)
            .setMetersBetweenUpdates(100);
  1. Pour trouver la distance entre deux points sur Android, vous pouvez vérifier ceci: Obtenez la distance entre deux points géographiques

Les deux OS

En fonction d'une position relevée toutes les X secondes, vous devez réduire le temps entre les données de localisation pour améliorer la précision.

Comme vous voulez calculer la distance sur un contexte routier, configurez le gestionnaire de localisation en mode navigation, ce mode vous donne les coordonnées qui sont sur la route.

Enfin

Si vous souhaitez améliorer la précision de votre calcul de distance, vous pouvez utiliser une API Google: https://developers.google.com/maps/documentation/distance-matrix/intro

En définissant le bon paramètre mode:

Paramètres facultatifs

mode (par défaut à la conduite) - Spécifie le mode de transport à utiliser lors du calcul de la distance. Les valeurs valides et autres détails de demande sont spécifiés dans la section Modes de voyage de ce document.

20
Alban

Je travaille sur quelque chose de similaire sur Andoriod, mais les principes sont les mêmes pour iOS:

  1. Pour chaque échantillon GPS, vérifiez sa précision. S'il dépasse un certain seuil (disons 20 mètres), ignorez-le.
  2. N'oubliez pas que même si l'appareil mobile est statique, différents échantillons GPS vous donneront des emplacements différents, selon la précision. Une voiture immobile pendant longtemps dans un feu de circulation montrera que vous avez avancé de quelques dizaines de mètres, alors ajoutez une méthode qui détecte si le mobile est statique ou non. J'ai implémenté cela en lisant l'accéléromètre - si le delta entre deux lectures est supérieur à un certain seuil - l'appareil se déplace. S'il est trop petit, ignorez le GPS.
  3. Si vous avez l'intention de l'utiliser dans une voiture, vous pouvez lire le GPS chaque fois qu'il a une nouvelle lecture (dans Android utilisez la méthode onLocationChanged). Si vous l'utilisez pour courir/marche, tenez compte du fait que votre vitesse est lente - deux lectures consécutives seront relativement proches, mais en raison de la précision du GPS, vous pouvez obtenir une distance assez grande entre elles. Elle peut être corrigée en augmentant le temps entre deux lectures consécutives, ou en ignorant certains d'entre eux (c'est-à-dire ne prendre en compte que chaque 10e lecture).
  4. Utilisez la formule Haversine pour calculer la distance entre deux lectures consécutives. Dans Android cela peut être fait avec la méthode Location.distanceTo().

Vous devrez le tester par rapport au compteur kilométrique de votre voiture et ajuster les seuils de l'accéléromètre.

9
TDG

Vous pouvez obtenir plus de précision avec une combinaison des stratégies suivantes.

  1. Comme mentionné dans d'autres réponses, vous pouvez stocker la position du mobile toutes les X secondes (disons 10 secondes) en utilisant le GPS et mesurer le temps consécutif entre les points.

  2. Aussi, lorsque l'utilisateur effectue des virages rapides, assurez-vous de lire cela en utilisant également les valeurs du capteur magnétique, donc dans un tel cas, diminuez le "délai entre le stockage de la position" pour dire 1- 2 secondes (sera nécessaire pour la précision)

  3. Comme dernière étape, ( utilisez les données de la carte (comme Google Maps, etc.) pour vous assurer que vous êtes correctement suivi ( si sur route).

Et puis résumez toutes les valeurs pour obtenir la distance exacte.

P.S. J'ai donné des informations sur les stratégies seules, car je ne suis pas sûr de sa mise en œuvre dans Android (ou iOS).

J'espère que cela t'aides :)

7
Snazzy Sanoj

Il y a 4 ans, je viens de créer une application appelée Landsurvayor qui calcule la distance réelle de deux points géogra- phiques tracés sur Google Map. Je ne sais pas qui pourrait vous aider ou non, mais il existe une formule appelée formule Haversine qui calcule la distance réelle entre deux points géo-graphiques. Vous pourriez essayer et voir si cela vous est utile ou non. Voici l'exemple de code de la formule Haversine:

public double CalculationByDistance(double initialLat, double initialLong,
                            double finalLat, double finalLong){
int R = 6371; // km
double dLat = toRadians(finalLat-initialLat);
double dLon = toRadians(finalLong-initialLong);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);

double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
return R * c;
}

public double toRadians(deg) {
  return deg * (Math.PI/180)
}

En savoir plus sur la formule Haversine: https://en.wikipedia.org/wiki/Haversine_formula

Il existe une autre approche simple Android SDK intégrée pour calculer la distance entre deux lat, lng:

Location locationA = new Location("point A");     
locationA.setLatitude(latA); 
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB); 
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB) ;

J'espère que cela pourrait vous aider.

6
Gagan Singh

Si vous recherchez des informations de distance exactes (ou presque exactes), vous devez suivre le chemin suivi, ce qui signifie vérifier les coordonnées toutes les quelques secondes (en fonction de la vitesse attendue parcourue). Vous pouvez économiser de l'espace en supprimant les anciennes coordonnées après avoir calculé chaque segment et en stockant simplement la distance actuelle parcourue.

3
Calteran

Un problème avec l'utilisation des coordonnées GPS est qu'elles (évidemment) ne sont pas précises. Si vous voyagez en ligne droite, les coordonnées GPS peuvent vous montrer voyager sur un chemin en zig-zag, retournant ainsi une plus grande distance parcourue que la vraie distance. Même avec une bonne précision GPS, cette erreur peut être importante. L'utilisation de moins de coordonnées pourrait entraîner ou non un calcul plus précis.

Ce dont vous avez besoin est un moyen de lisser le chemin GPS tracé, en tenant dûment compte de votre précision requise (encore une fois un compromis).

Ma première pensée est de diviser les points en groupes et d'ajuster les segments de ligne à chaque groupe (recherchez "régression linéaire"). Trouvez ensuite où chaque paire de lignes consécutives se chevauchent pour définir chaque segment de ligne. Additionnez ensuite simplement la longueur des segments de ligne.

Vous pouvez ajuster les segments de courbe, mais c'est beaucoup plus intense mathématiquement et peut ne pas donner un meilleur résultat (et quelle formule de courbe utiliser?). Il y a peut-être de meilleures méthodes mathématiques que je ne connais pas.

J'espère que cela t'aides.

3
John Cook

Utilisez le GPS pour obtenir la lat lon des deux endroits et après avoir obtenu les deux, passez la méthode ci-dessous.

public static double getDistanceFromLatLonInKm(double lat1, double lon1,
        double lat2, double lon2) {



    double R = 6371; // Radius of the earth in km
    double dLat = deg2rad(lat2 - lat1); // deg2rad below
    double dLon = deg2rad(lon2 - lon1);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
            * Math.sin(dLon / 2) * Math.sin(dLon / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    double d = R * c; // Distance in km


    return d;

}

public static double deg2rad(double deg) {
    return deg * (Math.PI / 180);
}

}

3
Jotiram Chavan

Si la précision est critique, vous pouvez utiliser les données de l'accéléromètre et du gyroscope. Vous pouvez trouver une formule très simple pour résoudre une tâche cinématographique simple afin d'obtenir un acc dans l'axe global. Ensuite, il suffit d'utiliser l'intégrale deux fois (d'abord pour obtenir la vitesse, puis pour obtenir la position). Juste pour montrer une autre perspective.

3
muminers

Android :: comment calculer la distance en marchant dans android?

Il y a d'autres façons de le faire:

1.GPS: Continuez à ajouter une distance GPS entre 2 points toutes les X secondes (disons 10 secondes). Vérifiez Android Location.distanceTo ou distanceBetween. Vérifiez l'application My Tracks, elle est open source. Le GPS n'est pas disponible à l'intérieur et aurait une erreur si l'utilisateur change de direction très fréquemment (lire toutes les 1-2 secondes) ) 2. Accéléromètre: recherchez le code/la bibliothèque pour la détection de pas à l'aide de l'accéléromètre. La distance vient de la double intégration de l'accélération, les erreurs peuvent s'accumuler très rapidement ici. 3. Détecteur d'étape: intégré dans Nexus 5. Google doit avoir pris soin de erreurs d'accéléromètre dans la mesure du possible. Il s'agit d'un calcul basé sur le matériel, consomme moins de batterie mais n'est pas disponible sur la plupart des combinés à ce jour.

La 2ème option semble très similaire à ce que vous avez suggéré et je pense que c'est la meilleure façon d'y parvenir depuis iOS et Android différez dans le code et dans les fonctionnalités pour que la meilleure méthode pour y parvenir soit la sauvegarde currentLocation et previousLocation dans une boucle while qui (. sleep () et additionner simplement la boucle entière en fonction de la distance parcourue. La plus grande question est que cette application est censée être une application d'été à distance? Est-ce juste une petite fonction à l'intérieur? comment décidez-vous quand arrêter de calculer la distance?

3
Daniel Netzer

Enregistrez les points toutes les x secondes (peut-être 2-3?) Et utilisez la formule de distance ci-dessous pour chaque point enregistré.

Distance = sqrt((x2−x1)^2+(y2−y1)^2)

Résumez-les tous et vous obtenez de la distance

2
lawonga