The revolutionary project management tool is here! Plan visually with a single glance and make sure your projects get done.

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.

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.

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

For 1. you will also need coordinates of 1 airport.

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

Private Type Rad_Dist

Radial As Double

DME As Double

End Type

Dim LL As Lat_Lon

Dim RD As Rad_Dist

Private Function RadDist(inpData As Lat_Lon) As Rad_Dist

Dim dF As Double, dL As Double

dF = inpData.Lat - LatNavAid

dL = inpData.Lon - LonNavAid

If dF = 0 Then

RadDist.Radial = 90

Else

RadDist.Radial = Atn(dL * Cos(LatNavAid * PI / 180) / dF) * 180 / PI

End If

If RadDist.Radial < 0 Then RadDist.Radial = RadDist.Radial + 360

If dF < 0 Then RadDist.Radial = RadDist.Radial + 180

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

Text1 = RadDist(LL).Radial

Text2 = RadDist(LL).DME

End Sub

Private Sub Command2_Click()

RD.DME = 100

RD.Radial = 180

Text1 = LatLon(RD).Lat

Text2 = LatLon(RD).Lon

End Sub

Why you multiple degrees to 69.09398?

One Nautical miles = 1 minute, 1 degree=60 minutes

Cheers

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)."

arccos is positive (0 to 180 degrees) :)

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.

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

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...

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

All Courses

From novice to tech pro — start learning today.

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

Private Type Rad_Dist

Radial As Double

DME As Double

End Type

Dim LL As Lat_Lon

Dim RD As Rad_Dist

Private Function RadDist(inpData As Lat_Lon) As Rad_Dist

Dim dF As Double, dL As Double

dF = inpData.Lat - LatNavAid

dL = inpData.Lon - LonNavAid

If dF = 0 Then

RadDist.Radial = 90

Else

RadDist.Radial = Atn(Sin(Rad(dL)) / (Tan(Rad(inpData.Lat)) * Cos(Rad(LatNavAid)) - Sin(Rad(LatNavAid)) * Cos(Rad(dL)))) * 180 / PI

End If

If RadDist.Radial < 0 Then RadDist.Radial = RadDist.Radial + 360

If dF < 0 Then RadDist.Radial = RadDist.Radial + 180

If RadDist.Radial > 360 Then RadDist.Radial = RadDist.Radial - 360

RadDist.DME = Abs(Arccos(Sin(Rad(LatNavA

dL = 1

End Function

Private Function LatLon(inpData As Rad_Dist) As Lat_Lon

Dim dL As Double, tmp As Double

If inpData.Radial = 90 Or inpData.Radial = 270 Then

tmp = LatNavAid

Else

tmp = Arcsin(Cos(Rad(inpData.DME

End If

LatLon.Lat = tmp

If inpData.Radial = 0 Or inpData.Radial = 180 Then

dL = 0

Else

dL = Arcsin(Sin(Rad(inpData.DME

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