• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

FS2004 Lat/Lon distance calculation

Messages
1,043
Country
us-northcarolina
I am trying to calculate the distance between 2 points on earth...hum, probably 2 airports :D I have read the posts related to Haversine formula and visited 1/2 million web sites. I am using VB5 (yeah, old class). I adapted the formulas I found into code and though it all 'looks good' it doesn't work all that well. If anyone can give me a hint on what I am doing wrong I would appreciate.

References:
Haversine formula: http://www.ig.utexas.edu/outreach/googleearth/latlong.html
Atan2:http://en.wikibooks.org/wiki/Visual_Basic/Simple_Arithmetic

Data:
KGSO: N36* 06.079552',W079 56.467407'
KMYR: N33* 40.785000',W078 55.700000'
Calculated distance on utexas.edu is 284.7 km
Calculated distance on google is 315.4 km
My calculated distance is 122.6 km

Here is the code:

Code:
Private Const Pi As Double = 3.14159265358979


Public Function GetDistance(ByVal sValue1 As String, ByVal sValue2 As String) As Double
' sValue1 format: N36* 8.02',W80* 13.31

Dim R As Double
Dim dLat As Double
Dim dLon As Double
Dim dLat1 As Double
Dim dLon1 As Double
Dim dLat2 As Double
Dim dLon2 As Double
Dim a As Double
Dim c As Double

  CoordToDegree sValue1, dLat1, dLon1
  CoordToDegree sValue2, dLat2, dLon2

'  R = 3437.74677 '(nautical miles)
  R = 6378.7    '(kilometers)
'  R = 3963       '(statute miles)

  dLat1 = DegToRad(dLat1)
  dLon1 = DegToRad(dLon1)
  dLat2 = DegToRad(dLat2)
  dLon2 = DegToRad(dLon2)
  dLat = dLat2 - dLat1
  dLon = dLon2 - dLon1
  
  a = (Sin(dLat / 2) * Sin(dLat / 2)) + ((Cos(dLat1) * Cos(dLat2)) * (Sin(dLon / 2) * Sin(dLon / 2)))
  c = 2 * Atan2(Sqr(a), Sqr(1 - a))
  GetDistance = R * c
End Function

Public Sub CoordToDegree(ByVal sValue As String, ByRef dLon As Double, ByRef dLat As Double)
' [url]http://www.chocolatesoftware.com/forum/index.php?topic=839.0[/url]
Dim pos As Integer
Dim iDegree As Integer
Dim bMinus As Boolean
Dim cnt As Integer
Dim tmpStr As String

    tmpStr = sValue
    pos = InStr(1, tmpStr, ",")
    tmpStr = Right(tmpStr, Len(tmpStr) - pos)
redo:
    cnt = cnt + 1
    If UCase(Left(tmpStr, 1)) = "S" Or UCase(Left(tmpStr, 1)) = "W" Then bMinus = True
    tmpStr = Right(tmpStr, Len(tmpStr) - 1)
    pos = InStr(1, tmpStr, "* ")
    iDegree = Left(tmpStr, pos - 1)
    tmpStr = Right(tmpStr, Len(tmpStr) - (pos + 1))
    pos = InStr(1, tmpStr, "'")
    If cnt = 1 Then
        dLon = iDegree + (Left(tmpStr, pos - 1)) / 60
        If bMinus Then dLon = -dLon
    Else
        dLat = iDegree + (Left(tmpStr, pos - 1)) / 60
        If bMinus Then dLat = -dLat
    End If
    pos = InStr(1, sValue, ",")
    tmpStr = Left(sValue, pos - 1)
    If cnt = 1 Then GoTo redo
End Sub


Public Function DegToRad(ByVal dvalue As Double) As Double
    DegToRad = dvalue * (3.14159265358979 / 180)
End Function
 
I wish I could help but my VB went from my head years ago :o
 
ADE uses this all the time, of course. I used general spherical geometry to get the great circle distance which as I recall is the shortest distance between two points on the surface of the earth http://en.wikipedia.org/wiki/Great-circle_distance

I am not sure this will be any help but below is the code I use:

Code:
   public static double Distance(FSPoint startPoint, FSPoint endPoint) {
            double lat1 = FSConvert.DegreesToRadians(startPoint.Latitude.Decimal);
            double lon1 = FSConvert.DegreesToRadians(startPoint.Longitude.Decimal) * -1;
            double lat2 = FSConvert.DegreesToRadians(endPoint.Latitude.Decimal);
            double lon2 = FSConvert.DegreesToRadians(endPoint.Longitude.Decimal) * -1;

            double result = Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(lon1 - lon2));
            return FSConvert.DradtoMeters(result);

FSPoints are lat/lon pairs
Lats and Lons are decimal.

FSConvert.DegreesTo Radians is a routine to turn degrees into radians

FSConvert.DradtoMeters converts decimal radians back to meters. This basically multiplies the radians by the radius of the earth in meters.
 
Your distance is 248.33 km

There is simple formula for short distances (loxodromia) , but will not apply for say transocean distances where great circle calculation should be used .

cos(distance)=cos(Longitude difference)*cos(Lat1)*cos(Lat2)+/-(sin(Lat1)*sin(Lat2) ..... + if Lats are homonym, - if Lats heteronym

Once the cos(distance) is found get the appropriate degrees and minutes , multiply the degrees by 60 , add the minutes and you have the actuall distance in nautical miles .
 
Hi,

I gave your published code a try in VB6 and then searched for the possible issue for false calculating.

This is what I found:
Code:
CoordToDegree sValue1, dLat1, dLon1
The subroutine ist called in sequence with the parameters ..., dLat1, dLon1, but in
Code:
Sub CoordToDegree(..., ByRef dLon As Double, ByRef dLat As Double)
you refer to dLon first then to dLat. The order in the sub is correct, so change the calling sequence to dLon1, dLat1 (and of course do the same for dLon2, dLat2).

Two other things I found in the Subroutine CoordToDegree:

1. because you make a loop (:redo) you have to 'reset' bMinus to 'FALSE' after the first run.

2. your formula is taking W(est) Longitudes as positiv, so it should be
Code:
If UCase(Left(tmpStr, 1)) = "S" Or UCase(Left(tmpStr, 1)) = "E" Then bMinus = True
With these changes the VB Program has given me a result of ~285.01 km.
I compared this with a more sophisticated formula which gives me ~284.47 km.

Regards
Hans
 
You all are great, thank you for your help.

Danke schoen Hans, you nailed it. I'm not thorough enough in my debugging or maybe just getting too old to see the obvious :D
 
That was the major final step to completing my new baby (application) that basically creates random flight plans for AI. Pick a few parameters such as airline, aircraft, and a few more and plans are created on the fly. I will be willing to share it with you all after I test it a bit more...or if you guys are interested in playing around with it you are welcome to let me know.

BG
BG


Edit: larger pictures
 
Last edited:
Back
Top