437 Stimmen

Berechnen Sie die Entfernung zwischen 2 GPS-Koordinaten

Wie berechne ich die Entfernung zwischen zwei GPS-Koordinaten (unter Verwendung von Breitengrad und Längengrad)?

3 Stimmen

Dieser Algorithmus ist als die Großkreisdistanz bekannt.

0 Stimmen

@GregHewgill, der erste Satz dieses Artikels besagt "Dieser Artikel handelt von der kürzesten Entfernung auf einer Kugel." Also offensichtlich nicht anwendbar auf GPS-Koordinaten.

8voto

Tod Samay Punkte 164

I. In Bezug auf die Methode "Breadcrumbs"

  1. Der Erdradius ist unterschiedlich bei unterschiedlichen Breitengraden. Dies muss im Haversine-Algorithmus berücksichtigt werden.
  2. Beachten Sie die Änderung des Kurses, die gerade Linien in Bögen verwandelt (die länger sind).
  3. Die Berücksichtigung von Geschwindigkeitsänderungen verwandelt Bögen in Spiralen (die länger oder kürzer sind als Bögen).
  4. Änderungen in der Höhe verwandeln flache Spiralen in 3D-Spiralen (die wiederum länger sind). Dies ist besonders wichtig für hügelige Gebiete.

Im Folgenden finden Sie die Funktion in C, die #1 und #2 berücksichtigt:

double calcDistanceByHaversine(double rLat1, double rLon1, double rHeading1,
       double rLat2, double rLon2, double rHeading2){
  double rDLatRad = 0.0;
  double rDLonRad = 0.0;
  double rLat1Rad = 0.0;
  double rLat2Rad = 0.0;
  double a = 0.0;
  double c = 0.0;
  double rResult = 0.0;
  double rEarthRadius = 0.0;
  double rDHeading = 0.0;
  double rDHeadingRad = 0.0;

  if ((rLat1 < -90.0) || (rLat1 > 90.0) || (rLat2 < -90.0) || (rLat2 > 90.0)
              || (rLon1 < -180.0) || (rLon1 > 180.0) || (rLon2 < -180.0)
              || (rLon2 > 180.0)) {
        return -1;
  };

  rDLatRad = (rLat2 - rLat1) * DEGREE_TO_RADIANS;
  rDLonRad = (rLon2 - rLon1) * DEGREE_TO_RADIANS;
  rLat1Rad = rLat1 * DEGREE_TO_RADIANS;
  rLat2Rad = rLat2 * DEGREE_TO_RADIANS;

  a = sin(rDLatRad / 2) * sin(rDLatRad / 2) + sin(rDLonRad / 2) * sin(
              rDLonRad / 2) * cos(rLat1Rad) * cos(rLat2Rad);

  if (a == 0.0) {
        return 0.0;
  }

  c = 2 * atan2(sqrt(a), sqrt(1 - a));
  rEarthRadius = 6378.1370 - (21.3847 * 90.0 / ((fabs(rLat1) + fabs(rLat2))
              / 2.0));
  rResult = rEarthRadius * c;

  // Korrektur von Sehne zu Bogen basierend auf Kursänderungen. Wichtig für Strecken mit vielen Kurven und Wendungen

  if ((rHeading1 >= 0.0) && (rHeading1 < 360.0) && (rHeading2 >= 0.0)
              && (rHeading2 < 360.0)) {
        rDHeading = fabs(rHeading1 - rHeading2);
        if (rDHeading > 180.0) {
              rDHeading -= 180.0;
        }
        rDHeadingRad = rDHeading * DEGREE_TO_RADIANS;
        if (rDHeading > 5.0) {
              rResult = rResult * (rDHeadingRad / (2.0 * sin(rDHeadingRad / 2)));
        } else {
              rResult = rResult / cos(rDHeadingRad);
        }
  }
  return rResult;
}

II. Es gibt einen einfacheren Weg, der ziemlich gute Ergebnisse liefert.

Mit durchschnittlicher Geschwindigkeit.

Strecke = Durchschnittsgeschwindigkeit * Fahrzeit

Da die GPS-Geschwindigkeit durch den Dopplereffekt erkannt wird und nicht direkt mit [Lon,Lat] in Verbindung steht, kann sie zumindest als sekundäre (Backup- oder Korrektur-) Methode für die Abstandsberechnung in Betracht gezogen werden.

8voto

Henry Vilinskiy Punkte 91

Eine T-SQL-Funktion, die ich verwende, um Datensätze nach Entfernung für ein Zentrum auszuwählen

Create Function  [dbo].[DistanceInMiles] 
 (  @fromLatitude float ,
    @fromLongitude float ,
    @toLatitude float, 
    @toLongitude float
  )
   returns float
AS 
BEGIN
declare @distance float

select @distance = cast((3963 * ACOS(round(COS(RADIANS(90-@fromLatitude))*COS(RADIANS(90-@toLatitude))+ 
SIN(RADIANS(90-@fromLatitude))*SIN(RADIANS(90-@toLatitude))*COS(RADIANS(@fromLongitude-@toLongitude)),15)) 
)as float) 
  return  round(@distance,1)
END

7voto

dsmelser Punkte 71

Wenn Sie etwas genaueres benötigen, dann schauen Sie sich hier an.

Die Vincenty-Formeln sind zwei verwandte iterative Methoden, die in der Geodäsie verwendet werden, um den Abstand zwischen zwei Punkten auf der Oberfläche eines Spheroids zu berechnen, entwickelt von Thaddeus Vincenty (1975a). Sie basieren auf der Annahme, dass die Form der Erde ein abgeflachtes Spheroid ist, und sind daher genauer als Methoden wie die Großkreisdistanz, die von einer sphärischen Erde ausgehen.

Die erste (direkte) Methode berechnet die Position eines Punktes, der einen gegebenen Abstand und Azimut (Richtung) von einem anderen Punkt hat. Die zweite (umgekehrte) Methode berechnet den geografischen Abstand und Azimut zwischen zwei gegebenen Punkten. Sie wurden in der Geodäsie weit verbreitet eingesetzt, da sie auf dem Erdellipsoid eine Genauigkeit von 0,5 mm (0,020) haben.

7voto

Tim Partridge Punkte 3285

Wenn Sie .NET verwenden, erfinden Sie das Rad nicht neu. Siehe System.Device.Location. Dank an fnx in den Kommentaren in einer anderen Antwort.

using System.Device.Location;

double lat1 = 45.421527862548828D;
double long1 = -75.697189331054688D;
double lat2 = 53.64135D;
double long2 = -113.59273D;

GeoCoordinate geo1 = new GeoCoordinate(lat1, long1);
GeoCoordinate geo2 = new GeoCoordinate(lat2, long2);

double distance = geo1.GetDistanceTo(geo2);

6voto

Sai Li Punkte 635

Hier ist die Swift-Implementierung aus der Antwort

func degreesToRadians(degrees: Double) -> Double {
    return degrees * Double.pi / 180
}

func distanceInKmBetweenEarthCoordinates(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {

    let earthRadiusKm: Double = 6371

    let dLat = degreesToRadians(degrees: lat2 - lat1)
    let dLon = degreesToRadians(degrees: lon2 - lon1)

    let lat1 = degreesToRadians(degrees: lat1)
    let lat2 = degreesToRadians(degrees: lat2)

    let a = sin(dLat/2) * sin(dLat/2) +
    sin(dLon/2) * sin(dLon/2) * cos(lat1) * cos(lat2)
    let c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return earthRadiusKm * c
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X