ARTICLE

Mapping with a GPS and VB.NET

Posted by Scott Lysle Articles | Visual Basic Language September 07, 2007
This article shall describe a very simple approach to working with a GPS device within the context of a Visual Basic 2005 application.
Download Files:
 
Reader Level:

Introduction

 

This article shall describe a very simple approach to working with a GPS device within the context of a Visual Basic 2005 application. This article does not address how the GPS device works or everything that can be gleaned from the NEMA 0183 string outputted from most GPS devices; rather, the article is intended for those just interested in getting present position from a GPS and using that point to do something interesting like show you where you are on a map.

 

Nothing exotic or expensive was used in this project; the GPS source was a provided by my Garmin eTrex Legend handheld GPS purchased for about $100.00 (a nice little GPS but not the high end to be sure). Since my laptop provides no male serial ports, in order to connect the device I needed an adapter; for this I opted to purchase a Belkin Serial Port to USB adapter (an F5U109) which works great; the cable used to connect the device to a computer was provided with the device.

 

 

Figure 1: Getting Present Position from the GPS

 

To make matters more interesting that just outputting present position, I provided the means to map the point directly into Google Maps using the query string accepted on that site populated with the current latitude and longitude of the device. I had published something similar on VB.NET Heaven a while back but without the GPS interface provided. Interestingly enough (but not surprising), if you compare the present position of the device as shown on the map versus the physical address when plotted on Google Maps, you will likely note that the GPS position is more accurate than the geocoded physical address.

 

NOTE: In order to retrieve present position from the GPS device, it is necessary to configure the device to output the NEMA 0183 complaint string. Refer to your owner's manuals to determine how to set that up with whatever device you may be using.

 

 

 

Figure 2: Google Maps Showing the Plotted Present Position

 

Getting Started

 

The solution contains a single Windows Forms project called "ReadGPS" which was written in Visual Basic 2005; the application contains two forms (frmPP.vb, frmMap.vb) and all of the code necessary to drive the application is contained in those two form classes.

 

 

 

Figure 3: Solution Explorer with the Project Visible

 

Code: Main Form (frmPP.vb)

 

All of the code necessary to derive present position from a GPS device is contained in this single form; the form shall be described entirely in this section.

 

The code for this form class begins with the following: 

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Data

Imports System.Drawing

Imports System.Text

Imports System.Windows.Forms

Imports System.IO.Ports

 

Public Class frmPP

       

Following the imports and the declaration of the form class, the next order of business in the application is to declare a collection of member variables requiring form wide scope; these variables are contained in a defined region entitled, "Member Variables". The declaration of the variables follows:

   

#Region "Member Variables"

' Local variables used to hold the present

' position as latitude and longitude

Public Latitude As String

Public Longitude As String

#End Region

 

The form designer contains a single serial port control along with some text boxes used to display present position as latitude and longitude, and two buttons, one of which is used to turn on and off automatic updating of present position and the other which serves to map the present position in Google Maps. The form also contains a timer control used to automatically update the coordinates, and a menu strip control which contains menu options used to change the COM port and to exit the application.

 

The next block of code in the form class is the constructor; in this instance, the constructor is used to try to open the serial port given its default configuration as set in the property pages at design time. For some of the properties associated with the control, it might make sense to allow for runtime configuration changes but, aside from the COM port used to attach the device to the computer, the control is properly configured to work with the GPS device; review the settings for the serial port control in the IDE to review the settings applied.

 

Aside from using the wrong port setting, there is little that can go wrong here but if the initial attempt to open the port fails, the constructor will display a message box showing the user the reason for the connection failure. A failure also disables the timer control used to command present position updates and alters the text on the button used to manually disable the update timer.

 

#Region "Constructor"

    Public Sub New()

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Try to open the serial port

        Try

            SerialPort1.Open()

        Catch ex As Exception

            MessageBox.Show(ex.Message)

            timer1.Enabled = False

            btnUpdate.Text = "Update"

            Return

        End Try

    End Sub

#End Region

 

Following the constructor, the event handlers used within the application are coded. The first is the timer control'00s tick event; this is the heart of the application in terms of getting the latitude and longitude extracted from the NEMA 0183 string outputted from the device.

 

The code first checks to see if the serial port is open and, if it is, it reads the the output of the device into a string variable. The string is split on the dollar sign symbol to break it up into a string array with each of the subordinate string contained in the output. We are looking for a string beginning with "GPGGA"; this substring contains the latitude and longitude information we are looking for and it is comma delimited. 

 

The whole GPGGA section contains other information besides latitude and longitude (such as time of day information, elevation, the number of satellites tracked, etc.). There are only four parts of the GPGGA section that we want, those sections contain the coordinates and the ordinals defining the position. The rest of the code converts the returned values into decimal degrees and passes them to the latitude and longitude member variables.

 

If we have valid coordinates, the function also enables the button used to map the point into Google Maps. If the values returned are invalid, the form will display "GPS Unavailable" in the latitude and longitude text boxes. If the serial port is closed, the latitude and longitude text boxes will be used to display the message "COM Port Closed"; in either case, the mapping button is also disabled.

 

Private Sub timer1_Tick(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles timer1.Tick

 

    If SerialPort1.IsOpen Then

 

        Dim data As String = SerialPort1.ReadExisting()

        Dim strArr() As String = data.Split("$")

        Dim i As Integer = 0

 

        If strArr.Length > 1 Then

 

            Try

                For i = 0 To strArr.Length

 

                    Dim strTemp As String = strArr(i)

                    Dim lineArr() As String = strTemp.Split(",")

 

                    If (lineArr(0) = "GPGGA") Then

 

                        Try

 

                            ' Latitude

                           Dim dLat As Double =

                            Convert.ToDouble(lineArr(2))

                            dLat = dLat / 100

                           Dim lat() As String =

                            dLat.ToString().Split(".")

                           Latitude = lineArr(3).ToString() +

                           lat(0).ToString() + _

                           "." + ((Convert.ToDouble(lat(1)) /

                           60)).ToString("#####")

 

                            ' Longitude

                           Dim dLon As Double =

                            Convert.ToDouble(lineArr(4))

                            dLon = dLon / 100

                           Dim lon() As String =

                            dLon.ToString().Split(".")

                           Longitude = lineArr(5).ToString() +

                           lon(0).ToString() + _

                           "." + ((Convert.ToDouble(lon(1)) /

                           60)).ToString("#####")

 

                            ' Display

                            txtLat.Text = Latitude

                            txtLong.Text = Longitude

 

                            btnMapIt.Enabled = True

 

                        Catch

 

                            ' Can't Read GPS values

                            txtLat.Text = "GPS Unavailable"

                            txtLong.Text = "GPS Unavailable"

                            btnMapIt.Enabled = False

 

                        End Try

                    End If

                Next

            Catch

                'do nothing

            End Try

        End If

    Else

        txtLat.Text = "COM Port Closed"

        txtLong.Text = "COM Port Closed"

        btnMapIt.Enabled = False

    End If

End Sub

 

The following button click event handler is used to enable or disable the timer used to automatically update the present position value shown in the form. The click event handler will also alter the text displayed on the button in response to enabling or disabling the timer.

 

Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles btnUpdate.Click

 

    ' cycle timer

    If timer1.Enabled = True Then

        timer1.Enabled = False

    Else

        timer1.Enabled = True

    End If

    ' update button label

    If btnUpdate.Text = "Update" Then

        btnUpdate.Text = "Stop Updates"

    Else

        btnUpdate.Text = "Update"

    End If

End Sub

 

The next bit of code is merely used to exit the application in response to the the exit menu option click event.

 

Private Sub exitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles exitToolStripMenuItem.Click

    Application.Exit()

End Sub

 

The following bit of code is used to swap the serial port over to COM1.

 

Private Sub toolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolStripMenuItem2.Click

    Try

        SerialPort1.Close()

        SerialPort1.PortName = "COM1"

        SerialPort1.Open()

    Catch ex As Exception

        MessageBox.Show(ex.Message, "COM1")

    End Try

End Sub

 

The following bit of code is used to swap the serial port over to COM2.

 

Private Sub toolStripMenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolStripMenuItem3.Click

    Try

        SerialPort1.Close()

        SerialPort1.PortName = "COM2"

        SerialPort1.Open()

    Catch ex As Exception

        MessageBox.Show(ex.Message, "COM2")

    End Try

 End Sub

 

The following bit of code is used to swap the serial port over to COM3.

 

Private Sub toolStripMenuItem4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolStripMenuItem4.Click

    Try

        SerialPort1.Close()

        SerialPort1.PortName = "COM3"

        SerialPort1.Open()

    Catch ex As Exception

        MessageBox.Show(ex.Message, "COM3")

    End Try

 End Sub

       

The following bit of code is used to swap the serial port over to COM4.

 

Private Sub toolStripMenuItem5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolStripMenuItem5.Click

 

    Try

        SerialPort1.Close()

        SerialPort1.PortName = "COM4"

        SerialPort1.Open()

    Catch ex As Exception

        MessageBox.Show(ex.Message, "COM4")

    End Try

End Sub

 

The following bit of code is used to swap the serial port over to COM5.

 

Private Sub toolStripMenuItem6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolStripMenuItem6.Click

 

    Try

        SerialPort1.Close()

        SerialPort1.PortName = "COM5"

        SerialPort1.Open()

    Catch ex As Exception

        MessageBox.Show(ex.Message, "COM5")

    End Try

End Sub

 

The next bit of code is used to open up the Map form; the map form accepts a latitude and longitude as arguments. These arguments are passed to the new form and used to display the current location on the map.

 

Private Sub btnMapIt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMapIt.Click

 

    If Latitude <> String.Empty And Longitude <> String.Empty Then

        Dim f As New frmMap(Latitude, Longitude)

        f.Show()

    End If

End Sub

 

That wraps up the sum of the code used to communicate with the GPS device and to display the present position latitude and longitude from the NEMA 0183 string.

 

Code: Map Form (frmMap.vb)

 

This form class is used to display the position captured from the GPS device through Google Maps. The form contains only a single web browser control. The code contained in the class is used to form a query string around the latitude and longitude passed to the form whenever it is instantiated. Once the query string is assembled, the browser is commanded to navigate to the location indicated in that string.

 

The code is pretty simple and it is presented here in its entirety:

 

Imports System.Text

 

Public Class frmMap

    Public Sub New(ByVal lat As String, ByVal lon As String)

        InitializeComponent()

        If (lat = String.Empty Or lon = String.Empty) Then

            Me.Dispose()

        End If

 

        Try

 

            Dim queryAddress As New StringBuilder()

            queryAddress.Append("http://maps.google.com/maps?q=")

 

            If lat <> String.Empty Then

                queryAddress.Append(lat + "%2C")

            End If

 

            If lon <> String.Empty Then

                queryAddress.Append(lon)

            End If

            webBrowser1.Navigate(queryAddress.ToString())

        Catch ex As Exception

            MessageBox.Show(ex.Message.ToString(), "Error")

        End Try

    End Sub

End Class

 

Summary:

 

This article was intended to demonstrate a convenient means for capturing present position information from a GPS device linked to a computer through a serial port. The project could easily be extended by reviewing the contents of the NEMA 0183 standard and picking out additional information from the information captured from a GPS device.

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# Corner (http://www.c-sharpcorner.com/).

Login to add your contents and source code to this article
Article Extensions
Contents added by paul mudgway on Aug 11, 2010
Hi Scott

I am new to this game, and I have a rudimentary versio I developed in Access VBA.
It is cumbersome, and this process you have outlined here is perfect for me to expand on.
can this process be used in VBA or do I need to swap my application to something .net?

I have been atempting to download your files from here, but it is not happening??

Paul

share this article :
post comment
 

Fantastic! I am so grateful!

Posted by Henrik Dahl Jan 25, 2012

.

Posted by peter watson Feb 15, 2011

hi! I read this article just now and it is very interesting. I just hope you sleep much more than time screenshoted from your desktop posted here! ;)

Posted by daniele perugini Jun 17, 2010

Hi there,


Are you able to explain what difference it makes to process the GPS data using a timer.Tick event, rather than handling it in the serialPort.DataReceived event? I have always used the latter but sometimes encounter problems, so am looking at alternative methods.

Thanks!

Gemma

Posted by Gemma Dec 02, 2009

Hi,

     It is a nice article which is useful for students who are working on GPS and to learn new programming language.I had one question about this.Since this article is based on serial port to usb adapter.Instead of serial port if I use garmin gps 18x USB  and use same code written by you,will it give me same NMEA string output sentences,latitude and longitude positions as same as serial port.

     Also If I use Garmin gps 18x usb,can the code be same as yours or do I need to do any modifications.If so could you please tell me those modifications.

Posted by swapna boppana Oct 13, 2009
Team Foundation Server Hosting
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Nevron Diagram
Become a Sponsor