다음을 통해 공유


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

Download

Download on MSDN (VB2008)