Distance between two GPS points with altitude

Informatix

Expert
Licensed User
Longtime User
Hello,

I didn't find a working formula to compute the distance between two GPS points with altitude (I mean I found formulas on various sites but none of them gave something close to the real distance; I don't know why). I need a great accuracy. So if anyone knows how to compute that...
 

Informatix

Expert
Licensed User
Longtime User
For information, the working formula for a flat ground is:
Distance = ACos(SinD(Lat0) * SinD(Lat1) + CosD(Lat0) * CosD(Lat1) * CosD(Lon0 - Lon1)) * 6378000

I need a formula that takes into account the altitude.

EDIT: I multiplied the result by 1000 to get the distance in meters.
 
Last edited:

wonder

Expert
Licensed User
Longtime User
@Informatix, are you writing some sort of PokemonGO? :D
 

Informatix

Expert
Licensed User
Longtime User
Here's the converted code:
B4X:
Private Sub EarthRadiusInMeters (latitudeRadians As Double) As Double
    ' latitude is geodetic, i.e. that reported by GPS
    ' http://en.wikipedia.org/wiki/Earth_radius
    Dim Const eqR As Double = 6378137.0 ' equatorial radius in meters
    Dim Const polR As Double = 6356752.3 ' polar radius in meters
    Dim CosLat As Double = Cos(latitudeRadians)
    Dim SinLat As Double = Sin(latitudeRadians)
    Dim t1 As Double = eqR * eqR * CosLat
    Dim t2 As Double = polR * polR * SinLat
    Dim t3 As Double = eqR * CosLat
    Dim t4 As Double = polR * SinLat
    Return Sqrt((t1*t1 + t2*t2) / (t3*t3 + t4*t4))
End Sub

Private Sub GeocentricLatitude(Lat As Double) As Double
    ' Convert geodetic latitude 'lat' to a geocentric latitude.
    ' Geodetic latitude is the latitude As given by GPS.
    ' Geocentric latitude is the angle measured from center of Earth between a point and the equator.
    ' https://en.wikipedia.org/wiki/Latitude#Geocentric_latitude
    Dim Const e2 As Double = 0.00669437999014
    Return ATan((1.0 - e2) * Tan(Lat))
End Sub

Private Sub LocationToPoint (Latitude As Double, Longitude As Double, Altitude As Int) As Double(3)
    ' Convert (Lat, Lon, elv) To (x, y, z).
    Dim Lat As Double = Latitude * cPI / 180.0
    Dim Lon As Double = Longitude * cPI / 180.0
    Dim radius As Double = EarthRadiusInMeters(Lat)
    Dim clat As Double   = GeocentricLatitude(Lat)

    Dim cosLon As Double = Cos(Lon)
    Dim sinLon As Double = Sin(Lon)
    Dim cosLat As Double = Cos(clat)
    Dim sinLat As Double = Sin(clat)
    Dim XYZ(3) As Double
    XYZ(0) = radius * cosLon * cosLat
    XYZ(1) = radius * sinLon * cosLat
    XYZ(2) = radius * sinLat

    ' We used geocentric latitude to calculate (x,y,z) on the Earth's ellipsoid.
    ' Now we use geodetic latitude to calculate normal vector from the surface, to correct for elevation.
    Dim cosGlat As Double = Cos(Lat)
    Dim sinGlat As Double = Sin(Lat)

    Dim nx As Double = cosGlat * cosLon
    Dim ny As Double = cosGlat * sinLon
    Dim nz As Double = sinGlat

    XYZ(0) = XYZ(0) + (Altitude * nx)
    XYZ(1) = XYZ(1) + (Altitude * ny)
    XYZ(2) = XYZ(2) + (Altitude * nz)
    Return XYZ
End Sub

Public Sub DistanceInMeters(Lat1 As Double, Long1 As Double, Alt1 As Int, Lat2 As Double, Long2 As Double, Alt2 As Int) As Double
    Dim XYZ1(3) As Double = LocationToPoint(Lat1, Long1, Alt1)
    Dim XYZ2(3) As Double = LocationToPoint(Lat2, Long2, Alt2)
    Dim dx As Double = XYZ1(0) - XYZ2(0)
    Dim dy As Double = XYZ1(1) - XYZ2(1)
    Dim dz As Double = XYZ1(2) - XYZ2(2)
    Return Sqrt (dx*dx + dy*dy + dz*dz)
End Sub
Edit: I removed "/ 1000" to the result to get the distance in meters.
 
Last edited:
D

Deleted member 103

Guest
Hi Informatix ,

can you tell me where the difference is between your code and my code?
B4X:
Sub get3Ddistance(Location1 As Location, Location2 As Location) As Float
    Dim distance As Float = Location1.DistanceTo(Location2)
    Dim Altitude As Float = Location1.Altitude - Location2.Altitude
   
    If Location1.AltitudeValid And Location2.AltitudeValid Then
        Return Sqrt(Power(distance,2) + Power(Altitude,2))
    Else
        Return distance
    End If
End Sub
 
D

Deleted member 103

Guest
Here is a small example with the 2 variants.

B4X:
    LocationA.Initialize
    LocationA.Latitude = 48.775846
    LocationA.Longitude = 9.182932
    LocationA.Altitude = 249
   
    LocationB.Initialize
    LocationB.Latitude =  48.775813
    LocationB.Longitude = 9.183163
    LocationB.Altitude = 255

1.Result with:
B4X:
Log(get3Ddistance(LocationA, LocationB) / 1000)
0.018377532958984377

2.Result with:
B4X:
Log(DistanceInMeters(LocationA.Latitude, LocationA.Longitude, LocationA.Altitude, LocationB.Latitude, LocationB.Longitude, LocationB.Altitude))
0.018378179088130855
 

Attachments

  • gps-test.zip
    7.7 KB · Views: 344

Informatix

Expert
Licensed User
Longtime User
If I'm not mistaken, Fred's code takes into account the curvature of the Earth, right?
Yes, but in fact the curvature is neglectable on small distances and so the Erel's code (or Filippo's one) should work. I thought initially the curvature had a greater impact and that neglecting it would lead to wrong results. I was wrong.
Let's see that with some code:
B4X:
Dim Lat0 As Double = 43.294026
Dim Lon0 As Double = 5.561624
Dim Lat1 As Double = 43.293313
Dim Lon1 As Double = 5.562475
Dim Alt0 As Int = 0
Dim Alt1 As Int = 0

Log("D1=" & (ACos(SinD(Lat0) * SinD(Lat1) + CosD(Lat0) * CosD(Lat1) * CosD(Lon0 - Lon1)) * 6378000))
Log("D2=" & (ACos(SinD(Lat0) * SinD(Lat1) + CosD(Lat0) * CosD(Lat1) * CosD(Lon0 - Lon1)) * EarthRadiusInMeters((Lat0+Lat1)/2)))
Dim Distance As Double = DistanceInMeters(Lat0, Lon0, Alt0, Lat1, Lon1, Alt1)
Log("D3=" & Distance)

Alt1 = 100
Log("D+A1=" & DistanceInMeters(Lat0, Lon0, Alt0, Lat1, Lon1, Alt1))
Log("D+A2=" & Sqrt(Power(Distance, 2) + Power(Alt1 - Alt0, 2)))
Between these two GPS coordinates, there are 105 meters. Google Maps measures 105,10 m.
D1 (no elevation, approximate computation) = 105.1357144446399
D2 (no elevation, the mean radius is used for the latitude) = 104.99633055287285
D3 (no elevation, more accurate computation) = 105.09049270240793

D+A1 (elevation +100m, accurate computation) = 145.0661398259639
D+A2 (elevation +100m, Erel's formula) = 145.06554262275674

Of course, if we increase distances and altitudes, differences appear more obviously:
B4X:
Dim Lat0 As Double = 43.294026
Dim Lon0 As Double = 5.561624
Dim Lat1 As Double = -15.293313
Dim Lon1 As Double = -5.562475
Dim Alt0 As Int = 0
Dim Alt1 As Int = 4200
Results in km:
Google maps=6612.74
D1=6619.894
D2=6598.257
D3=6293.736
D+A1=6295.822
D+A2=6293.738

Is Google Maps right or the Don Cross's formula? I would say the Don Cross's formula. Does someone know a site where we can check that? NASA site or something like that.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Here is a small example with the 2 variants.

B4X:
    LocationA.Initialize
    LocationA.Latitude = 48.775846
    LocationA.Longitude = 9.182932
    LocationA.Altitude = 249

    LocationB.Initialize
    LocationB.Latitude =  48.775813
    LocationB.Longitude = 9.183163
    LocationB.Altitude = 255

1.Result with:
B4X:
Log(get3Ddistance(LocationA, LocationB) / 1000)
0.018377532958984377

2.Result with:
B4X:
Log(DistanceInMeters(LocationA.Latitude, LocationA.Longitude, LocationA.Altitude, LocationB.Latitude, LocationB.Longitude, LocationB.Altitude))
0.018378179088130855
Yes, my mistake. I thought that the Earth curvature had a significant impact. It is not the case for distances < 100 km.
 
Top