VB.Net: Distances - As the crow flies
Overview
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("Country")
dt.Columns.Add("City")
dt.Columns.Add("Airport")
dt.Columns.Add("IATA")
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)))
Next
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)
InitializeComponent()
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.Clear()
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"))
Else
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"))
Else
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
Conclusion
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...