# Latitude/Longitude Conversion Problem

Here's the situation:
I need some assistance with converting the following:
Background:
1. In Air Navigation, devices known as Navigational Aids (Navaid) send out radio beams known as Radials ranging from 0 to 359 degrees. Distance from the navaid is also transmitted in nautical miles. (known as DME)
2. The latitude/longitude of the Navaid is a known constant.

The Problem:

I have tried everything I can think of to come up with this:
1. Given a Radial & DME, convert to standard Latitude & Longitude
2. Give a Latitude & Longitude, convert to a Radial & DME

Any assistance is greatly appreciated.
###### Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x

Commented:
Hi dantindall
Here is LongRange solution
Data formats:
Angle-degrees
Distance - miles
Latitude/longitude - degrees
works around the world :)
'----------------
Option Explicit
Const LatNavAid = 40
Const LonNavAid = 130
Const PI As Double = 3.14159265358979
Private Type Lat_Lon
Lat As Double
Lon As Double
End Type
DME As Double
End Type
Dim LL As Lat_Lon

Dim dF As Double, dL As Double
dF = inpData.Lat - LatNavAid
dL = inpData.Lon - LonNavAid
If dF = 0 Then
Else
End If
dL = 1
End Function

Private Function LatLon(inpData As Rad_Dist) As Lat_Lon
Dim dL As Double, tmp As Double
tmp = LatNavAid
Else
End If
LatLon.Lat = tmp
dL = 0
Else
End If
LatLon.Lon = LonNavAid + dL
End Function

Private Function Arccos(ByVal x As Double) As Double
If Abs(x) <> 1 Then
Arccos = Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1)
Else
Arccos = IIf(x = 1, 0, Atn(1) * 4)
End If
End Function

Private Function Arcsin(ByVal x As Double) As Double
If Abs(x) <> 1 Then
Arcsin = Atn(x / Sqr(-x * x + 1))
Else
Arcsin = IIf(x = 1, Atn(1) * 2, Atn(1) * 6)
End If
End Function

Private Function Rad(x As Double) As Double
Rad = x * PI / 180
End Function
0

Commented:
2.b distance

Option Explicit
Private Type tpInfo
ID As String
x As Double
y As Double
End Type
Dim airports(1 To 2) As tpInfo

Private Sub Form_Click()
airports(1).ID = "SJJ"
airports(1).x = 18.336
airports(1).y = 43.825

airports(2).ID = "NAP"
airports(2).x = 14.269
airports(2).y = 40.834

Dim dist As Double
dist = distance(airports(1).y, airports(1).x, airports(2).y, airports(2).x)
MsgBox dist
End Sub

Public Function distance(p1 As Double, t1 As Double, p2 As Double, t2 As Double) As Double
'arccos( Cos[p1]*Cos[p2]*Cos[t2 - t1] + Sin[p1]*Sin[p2] )
Dim x As Double
Dim rp1 As Double
Dim rt1 As Double
Dim rp2 As Double
Dim rt2 As Double
Dim PI As Double
PI = Atn(1) * 4        'calculate pi
rp1 = p1 * PI / 180    'change angles in degrees to radians
rt1 = t1 * PI / 180
rp2 = p2 * PI / 180
rt2 = t2 * PI / 180
'ozo's formula
x = Cos(rp1) * Cos(rp2) * Cos(rt2 - rt1) + Sin(rp1) * Sin(rp2)
'find angle, change back to degrees, and multiply by 69
distance = 69.09398 * Arccos(x) * (180 / PI)
End Function

Private Function Arccos(ByVal x As Double) As Double
'From the VB help - seems to handle -ve angles better
If Abs(x) <> 1 Then
Arccos = Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1)
Else
Arccos = IIf(x = 1, 0, Atn(1) * 4)
End If
End Function
0

Commented:
I'll see if I can find formula, or maybe expert 'ozo' has formula for 2.a (angle).
For 1. you will also need coordinates of 1 airport.
0

Commented:
Are DMEs short enough that we can assume two dimensions (i.e., can we assume the curvature of the earth has a negligible impact on the distance traveled)? This significantly simplifies the geometry.
0

Commented:
Hi dantindall
Here is solution for short distances. It will work fine if distance (DME) not exeed 200 nautical miles. If more, you will need 3D solution. Ameba show you how to calculate distanse (BTW, you need add ABS to the final formula - arccos may be negative, Dist - not). For Azimuth you can use followin formula
CtgA = tgF2*CosF1-SinF1*Cos(L2-L1)
where F1,F2 - Latitude, L2,L1 - Longitude. If you still need long range solution, I'll do it (my base education is Navigation, not air, but sea :))
'----------
Option Explicit
Const LatNavAid = 40
Const LonNavAid = 130
Const PI = 3.1415926
Private Type Lat_Lon
Lat As Double
Lon As Double
End Type
DME As Double
End Type
Dim LL As Lat_Lon

Dim dF As Double, dL As Double
dF = inpData.Lat - LatNavAid
dL = inpData.Lon - LonNavAid
If dF = 0 Then
Else
RadDist.Radial = Atn(dL * Cos(LatNavAid * PI / 180) / dF) * 180 / PI
End If
RadDist.DME = Sqr(dF ^ 2 + (dL * Cos(LatNavAid * PI / 180)) ^ 2)
End Function

Private Function LatLon(inpData As Rad_Dist) As Lat_Lon
Dim dF As Double, dL As Double
dF = inpData.DME * Cos(inpData.Radial * PI / 180) / 60
dL = inpData.DME * Sin(inpData.Radial * PI / 180) * Cos(LatNavAid * PI / 180) / 60
LatLon.Lat = LatNavAid + dF
LatLon.Lon = LonNavAid + dL
End Function
'-------------
'Using
Private Sub Command1_Click()
LL.Lat = 50
LL.Lon = 140
End Sub

Private Sub Command2_Click()
RD.DME = 100
Text1 = LatLon(RD).Lat
Text2 = LatLon(RD).Lon
End Sub
0

Commented:
2ameba

Why you multiple degrees to 69.09398?
One Nautical miles = 1 minute, 1 degree=60 minutes

Cheers
0

Commented:
>Why you multiple degrees to 69.09398?
Thanks for the correction, you are right, it's one minute of latitude:

"1 international nautical mile = 1.852 km = 1.1508 miles = 6076.1155 feet
The international nautical mile is also known as the international air mile.
The geographical nautical mile is 6080 feet (0.064% larger)."
0

Commented:
>BTW, you need add ABS to the final formula - arccos may be negative
arccos is positive (0 to 180 degrees) :)
0

Author Commented:
Ok,
this got over my head in a hurry. I now know why i never could get the solution on my own.
To clarify a couple of things:

BarryTice:
DME's are not known until runtime. User may want to enter a value of 179 degree Radial at 350 DME.

0

Author Commented:
Thanks to all for the assistance. I think that the answer is at hand.

Ark:
in both of the solutions, you have a couple of constants defined.
LatNavAid
LonNavAid
If I understand this correctly, I should place the Latitude & Longitude of my base navaid in those variables.
The Latitudes/Longitudes that I have and that my users will use are in the format:
Latitude:39,54,57
Longitude:80,54,57

How did you arrive at the values of 40 and 130 respectivly?

Additionally, I dropped the code into a form and placed 4 text boxes on it. Passing in a DME and Radial, the code returns a value in decimal format.
The program that this will be used in will need the latitude/longitudes in a format of:
latitude: 39,54,54
Longitude: 80,54,57
0

Commented:
Hi, dantindall, you can convert decimal degrees (DecDeg) to Deg, Min, Sec like this:
Deg = int(DecDeg)
Min = Int((DecDeg - Deg) * 60) 'decimal only * 60 minutes
Sec = Int((DecDeg - Deg - Min/60) * 60^2) 'remaining decimal of a degree * 3600 seconds - Min/60 gives the decimal portion for minutes.

The Int() function discards fractional seconds, and so forth.  To convert Deg, Min, Sec to DecDeg

DecDeg = Deg + Min/60 + Sec/(60^2) 'or Sec/3600, the number of seconds per degree.

HTH, good luck as usual...
0

Commented:
Hi dantindall
My functions both work with decimal format. Your input and output formats are strings. You can convert them to/from with following functions

Private Function Dec2Str(x As Double) As String
Dim Deg As Integer, Min As Integer, Sec As Integer
Dim y As Double
y = Abs(x)
Deg = Int(y)
Min = Right\$("0" & CStr(Int((y - Deg) * 60)), 2) & ","
Sec = Right\$("0" & CStr(Int((y - Deg - Min / 60) * 3600)), 2)
Dec2String = CStr(Deg) & "," & Right\$("0" & CStr(Int((y - Deg) * 60)), 2) & "," & Right\$("0" & CStr(Int((y - Deg - Min / 60) * 3600)), 2)
If x < 0 Then Dec2Str = "- " & Dec2Str
' or Dec2Str = Dec2Str & " S"
' or Dec2Str = Dec2Str & " W"
End Function

Private Function Str2Dec(x As String) As Double
Dim a As Integer, b As Integer
Dim y As String
If Left\$(x, 1) = "-" Then y = Mid\$(x, 2)
a = 0
For i = 0 To 1
b = InStr(a + 1, y, ",")
Str2Dec = Str2Dec + Val(Mid\$(y, a + 1, b - a)) / (60 ^ i)
a = b
Next i
Str2Dec = Str2Dec + Val(Mid\$(y, a + 1)) / 3600
If Left\$(x, 1) = "-" Then Str2Dec = Str2Dec * -1
End Function

'Using
'LatNavAid_Str = "39,54,54"
'LatNavAid_Dec = Str2Dec (LatNavAid_Str)
'output = 39.915

' My functions return data at decimal format. You can convert it to string, using Dec2Str function. In all calculations is better to use decimal format. If you need, I can change my functions for your format. I assumed that 39,54,54 meens 39 degrees, 54 minutes, 54 seconds - it's correct?

Cheers
Ark   ark@fesma.ru
0

Commented:
Great, Ark, that's just about how I would implement the actual code from the basic math.  Glad to meet you and dantindall.
good luck as usual...
0

Author Commented: