This application demonstrates the implementation of the haversine formula to determine the distance (as the crow flies) between any two of twelve thousand and fifty seven airports. Airports are used in this application as the latitude and longitude of airports is widely and freely available.

[Quote Wikipedia: https://en.wikipedia.org/wiki/Haversine_formula]

"The haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes. Important in navigation, it is a special case of a more general formula in spherical trigonometry, the law of haversines, that relates the sides and angles of spherical triangles."

The GUI uses two Airport UserControls, which each contain three ComboBoxes, and three Labels. The individual ComboBoxes are used to choose Country, City, and Airport. The UserControls expose Decimal latitude and longitude values through two Functions, named lat and lon.

To keep the application simple, a Form level DataTable is used, which is filled with data from a My.Resources Text File. In the creation of the UserControls, the DataTable is passed into the UserControl Constructor, so that filtered views from the table can be used in populating the ComboBoxes used for choosing departure and arrival airports.

To use the application, you'd first need to select a departure airport and an arrival airport, then simply clicking the command Button invokes the calculation code and the result is displayed in a Label.

The DataTable

The table is populated from data stored in a My.Resources Text file...

Dim dt As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Dim lines() As String = My.Resources.airports.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
 dt.Columns.Add("lat", GetType(Decimal))
 dt.Columns.Add("lon", GetType(Decimal))
 For Each l As String In lines
 dt.Rows.Add(l.Split(","c)(3), l.Split(","c)(2).Replace(" - ", ", "), l.Split(","c)(1), l.Split(","c)(4), CDec(l.Split(","c)(6)), CDec(l.Split(","c)(7)))
End Sub

The Airport UserControl code

The UserControls are the means of selecting Airports, and also provide latitude and longitude coordinates for the selected Airports...

The entire DataTable is passed to each UserControl in its constructor. Filtered views are used as datasources for the three ComboBoxes.

There is one simple custom Event, which is raised when a new Airport is selected.

Public Class Airport
 Public Event Changed(ByVal sender As System.Object, ByVal e As System.EventArgs)
 Private dt As DataTable
 Public Sub New(ByVal title As String, ByVal dt As DataTable)
     Label3.Text = title
     Me.dt = dt
     Dim dv As New DataView(dt, "", "Country ASC", DataViewRowState.CurrentRows)
     ComboBox1.DataSource = dv.ToTable(True, "Country")
     ComboBox1.DisplayMember = "Country"
     ComboBox1.SelectedIndex = -1
     ComboBox1.SelectedIndex = 0
 End Sub
 Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
     Dim dv As New DataView(dt, "Country = '" & ComboBox1.Text & "'", "City ASC", DataViewRowState.CurrentRows)
     ComboBox2.DataSource = dv.ToTable(True, "City")
     ComboBox2.DisplayMember = "City"
 End Sub
 Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
     Dim dv As New DataView(dt, "City = '" & ComboBox2.Text & "'", "Airport ASC", DataViewRowState.CurrentRows)
     ComboBox3.DataSource = dv
     ComboBox3.DisplayMember = "Airport"
     Label2.DataBindings.Add("Text", dv, "IATA")
 End Sub
 Public Function lat() As Decimal
     Dim drv As DataRowView = TryCast(ComboBox3.SelectedItem, DataRowView)
     If Not drv Is Nothing Then
         Return CDec(drv.Item("lat"))
         Return Nothing
     End If
 End Function
 Public Function lon() As Decimal
     Dim drv As DataRowView = TryCast(ComboBox3.SelectedItem, DataRowView)
     If Not drv Is Nothing Then
         Return CDec(drv.Item("lon"))
         Return Nothing
     End If
 End Function
 Private Sub Label2_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Label2.TextChanged
     RaiseEvent Changed(Me, New EventArgs)
 End Sub
End Class


This application demonstrates how basic DataBinding, using  only ADO.NET objects can produce useful and compact programs, that rival LINQ methods for speed of operation...


Download on MSDN (VB2008)