21 votes

Obtenir la direction (boussole) avec deux points de longitude/latitude

Je travaille sur une "boussole" pour un appareil mobile. J'ai les points suivants:

point 1 (emplacement actuel): Latitude = 47.2246, Longitude = 8.8257
point 2 (emplacement cible): Latitude = 50.9246, Longitude = 10.2257

J'ai également les informations suivantes (de mon téléphone Android):

La direction de la boussole en degrés, qui pointe vers le nord. 
Par exemple, lorsque je dirige mon téléphone vers le nord, j'obtiens 0°

Comment puis-je créer une flèche "type boussole" qui me montre la direction vers le point?

Y a-t-il un problème mathématique pour cela?

MODIFICATION : D'accord, j'ai trouvé une solution, cela ressemble à ceci :

/**
 * Params: lat1, long1 => Latitude et Longitude du point actuel
 *         lat2, long2 => Latitude et Longitude du point cible
 *         
 *         headX       => Valeur x de la boussole intégrée au téléphone
 * 
 * Renvoie le degré d'une direction du point actuel au point cible
 *
 */
function getDegrees(lat1, long1, lat2, long2, headX) {

    var dLat = toRad(lat2-lat1);
    var dLon = toRad(long2-long1);

    lat1 = toRad(lat1);
    lat2 = toRad(lat2);

    var y = Math.sin(dLon) * Math.cos(lat2);
    var x = Math.cos(lat1)*Math.sin(lat2) -
            Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
    var brng = toDeg(Math.atan2(y, x));

    // Corriger les degrés négatifs
    if(brng<0) {
        brng=360-Math.abs(brng);
    }

    return brng - headX;
}

20voto

liquified Points 145

Je ai oublié de dire que j'ai finalement trouvé la réponse. L'application consiste à déterminer la direction de la boussole d'un véhicule de transport en commun et de sa destination. Essentiellement, mathématiques fantaisie pour acquérir la courbure de la Terre, trouver un angle / une lecture de boussole, puis faire correspondre cet angle à une valeur de boussole générique. Vous pourriez bien sûr simplement conserver la compassReading et l'appliquer comme une quantité de rotation pour votre image. Veuillez noter qu'il s'agit d'une détermination moyenne de la direction du véhicule jusqu'au point final (gare routière), ce qui signifie qu'il ne peut pas savoir ce que fait la route (donc cela s'applique probablement le mieux aux avions ou au roller derby).

//exemple de données d'objet contenant des points lat et lng
//emplacement d'arrêt - le point d'extrémité du rayon
endpoint.lat = 44.9631;
endpoint.lng = -93.2492;

//emplacement du bus depuis le sud-est - le centre du cercle
startpoint.lat = 44.95517;
startpoint.lng = -93.2427;

function vehicleBearing(endpoint, startpoint) {
    endpoint.lat = x1;
    endpoint.lng = y1;
    startpoint.lat = x2;
    startpoint.lng = y2;

    var radians = getAtan2((y1 - y2), (x1 - x2));

    function getAtan2(y, x) {
        return Math.atan2(y, x);
    };

    var compassReading = radians * (180 / Math.PI);

    var coordNames = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"];
    var coordIndex = Math.round(compassReading / 45);
    if (coordIndex < 0) {
        coordIndex = coordIndex + 8
    };

    return coordNames[coordIndex]; // retourne la valeur de coordonnée
}

c'est-à-dire : vehicleBearing(mybus, busstation) pourrait renvoyer "NO" ce qui signifie qu'il se déplace vers le nord-ouest

2voto

deya tri Points 49

J'ai trouvé quelques formules de coordonnées GPS utiles en mathématiques ici. Pour ce cas, voici ma solution

 private double getDirection(double lat1, double lng1, double lat2, double lng2) {

    double PI = Math.PI;
    double dTeta = Math.log(Math.tan((lat2/2)+(PI/4))/Math.tan((lat1/2)+(PI/4)));
    double dLon = Math.abs(lng1-lng2);
    double teta = Math.atan2(dLon,dTeta);
    double direction = Math.round(Math.toDegrees(teta));
    return direction; //direction en degrés

}

0voto

Vivek Points 97

Je n'ai pas bien compris votre solution, calculer la pente a fonctionné pour moi. Pour modifier sur efwjames 's et votre réponse. Cela devrait faire -

import math
def getDegrees(lat1, lon1, lat2, lon2,head):
    dLat = math.radians(lat2-lat1)
    dLon = math.radians(lon2-lon1)
    bearing = math.degrees(math.atan2(dLon, dLat))
    return head-bearing

-3voto

StaWho Points 2478

Vous auriez besoin de calculer un vecteur euclidien entre votre point de départ et votre point d'arrivée, puis calculer son angle (disons par rapport à l'axe X positif) qui serait l'angle que vous voulez faire pivoter votre flèche.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X