Plot Latitude and Longitude with Geocoder Web Service in VB.NET

Introduction:

Geocoder.us offers a free (for non-commercial use) web service that may be used to geocode physical addresses. The details of the service and usage terms may be located at:
http://geocoder.us/. In general, the Geocoding service is based upon the use of Tiger/Line data gathered by the US Census bureau. Geocoding is defined as the process of estimating the latitude and longitude of a physical address. Naturally the service is based upon physical addresses so its use is limited to tagging physical addresses with a lat/long. Also, since this is based upon US Census Bureau data, only US addresses can be geocoded using the service and the accuracy of the data is largely dependent upon the quality of the Census Bureau data.

This article will demonstrate the basics of submitting an address to the service, recovering and displaying the geocoded result, and will also demonstrate a simple approach to displaying the location by mapping it with Yahoo! maps. 

The service can be used to obtain and store latitude and longitude on all of the addresses contained in some sort of contact database or asset location database, or might be useful for storing waypoints in a GPS navigation device. 

The demonstration application will evoke the web service to find the coordinates for a physical address and will display the best result along with any other addresses that match the search criteria. In Figure 1, note that the search term, "100 Peachtree, Atlanta, GA" was sent to the service; the best result is displayed in the "Best Match" group and all matches are displayed in the "All Possible Matches" group box. Since "Peachtree" is a very common name for a street in Atlanta where it is apparently the civic pastime to name streets "Peachtree", the data grid view control contained in the "All Possible Matches" group is pretty full. 

Geocoder-Vb.net.gif

Figure 1: The demonstration application running

Yahoo-Map-Vb.net.gif

Figure 2: Displaying the coordinates in Yahoo Maps

Getting Started:

In order to get started, unzip the included project and open the solution in the Visual Studio 2005 environment. In the solution explorer, you should note these files (Figure 3) along with a web reference pointing to 
http://rpc.geocoder.us/dist/eg/clients/GeoCoder.wsdl:


Figure 3: Solution Explorer

The Main Form (Form1.vb).

The main form is the only form contained in the application; all of the application specific code required to access the service, return the results of an address search, and to display those results as text or as a map are included in this class.
The code is pretty simple, if you'd care to open the code view up in the IDE you will see that the code file begins as follows:
Public Class Form1

Public Class Form1

    ''' <summary>
    ''' Default Constructor
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub New() 

        ' This call is required by the Windows Form Designer.
 

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

 

    End Sub 

The next section of the code is used to parse the results returned from the web service and to display the results to the user in the "Best Match" and "All Possible Matches" groups. The code is annotated to describe what each part of the code does.
 

    ''' <summary>

    ''' Use the geocoder.us web service

    ''' to geocode and address; display both

    ''' the best matching address along

    ''' with a collection of all addresses

    ''' meeting the search criteria

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub GetLatLong(ByVal sender As Object, _ByVal e Asus.geocoder.rpc.geocode_addressCompletedEventArgs)

 

        Try
 

            ' the address is broken up into parts so

            ' reassemble them into a street address using

            ' only the parts that have been populated

            ' by the service 

            ' start with the street number

            txtStreet.Text = e.Result(0).number.ToString() + " "

 

            ' add the prefix (e.g., N, SE, etc.)

            If e.Result(0).prefix.ToString() <> String.Empty Then

                txtStreet.Text += e.Result(0).prefix.ToString() + " "

            End If

 

            ' add the street name

            If e.Result(0).street.ToString() <> String.Empty Then

                txtStreet.Text += e.Result(0).street.ToString() + " "

            End If

 

            ' add the suffix (if any)

            If e.Result(0).suffix.ToString() <> String.Empty Then

                txtStreet.Text += e.Result(0).suffix.ToString() + " "

            End If

 

            'add the street type (e.g., ST, CT, RD, PKWY, etc.)

            If e.Result(0).type.ToString() <> String.Empty Then

                txtStreet.Text += e.Result(0).type.ToString()

            End If

 

            ' add the city, state, and zip

            txtCity.Text = e.Result(0).city.ToString()

            txtState.Text = e.Result(0).state.ToString()

            txtZip.Text = e.Result(0).zip.ToString()

 

            ' display the latitude and longitude

            txtLatitude.Text = e.Result(0).lat.ToString()

            txtLongitude.Text = e.Result(0).long.ToString()

 

 

            ' create a datatable to hold any additional

            ' possible address matches

            Dim dt As New DataTable()

 

            ' define all of the columns and add them

            ' to the data table

            Dim dcAddress As New DataColumn()

 

            dcAddress.DataType = System.Type.GetType("System.String")

            dcAddress.ColumnName = "Address"

            dcAddress.Caption = "Address"

            dt.Columns.Add(dcAddress)

 

            Dim dcCity As New DataColumn()

            dcCity.DataType = System.Type.GetType("System.String")

            dcCity.ColumnName = "City"

            dcCity.Caption = "City"

            dt.Columns.Add(dcCity)

 

            Dim dcState As New DataColumn()

            dcState.DataType = System.Type.GetType("System.String")

            dcState.ColumnName = "State"

            dcState.Caption = "State"

            dt.Columns.Add(dcState)

 

            Dim dcZip As New DataColumn()

            dcZip.DataType = System.Type.GetType("System.String")

            dcZip.ColumnName = "Zip Code"

            dcZip.Caption = "Zip"

            dt.Columns.Add(dcZip)

 

            Dim dcLat As New DataColumn()

            dcLat.DataType = System.Type.GetType("System.String")

            dcLat.ColumnName = "Latitude"

            dcLat.Caption = "Lat"

            dt.Columns.Add(dcLat)

 

            Dim dcLong As New DataColumn()

            dcLong.DataType = System.Type.GetType("System.String")

            dcLong.ColumnName = "Longitude"

            dcLong.Caption = "Lon"

            dt.Columns.Add(dcLong)

 

            ' create a row

            Dim row As DataRow

 

            ' loop through all of the results and

            ' add each row to the data table for

            ' display in the All Possible Matches

            ' datagridview control

            Dim i As Int32

            For i = 0 To e.Result.Length - 1

 

                ' create a new row

                row = dt.NewRow()

 

                ' build a street address

                Dim addr As String = e.Result(i).number.ToString() & " "

 

                If e.Result(i).prefix.ToString() <> String.Empty Then

                    addr += e.Result(0).prefix.ToString() + " "

                End If

 

                If e.Result(i).street.ToString() <> String.Empty Then

                    addr += e.Result(i).street.ToString() + " "

                End If

 

                If e.Result(i).suffix.ToString() <> String.Empty Then

                    addr += e.Result(i).suffix.ToString() + " "

                End If

 

                If e.Result(i).type.ToString() <> String.Empty Then

                    addr += e.Result(i).type.ToString()

                End If

 

                ' set the street address

                row("Address") = addr

 

                ' set the city, state, and zip code

                row("City") = e.Result(i).city.ToString()

                row("State") = e.Result(i).state.ToString()

                row("Zip Code") = e.Result(i).zip.ToString()

 

                ' set the latitude and longitude

                row("Latitude") = e.Result(i).lat.ToString()

                row("Longitude") = e.Result(i).long.ToString()

 

                ' add the new row to the table

                dt.Rows.Add(row)

            Next

 

            ' configure and bind the grid to the table

            dgvMatches.DataSource = dt

 

            dgvMatches.SelectionMode = _

            DataGridViewSelectionMode.FullRowSelect

 

            dgvMatches.AutoSizeRowsMode = _

            DataGridViewAutoSizeRowsMode.AllCells

 

            dgvMatches.RowHeadersVisible = False

            dgvMatches.ScrollBars = ScrollBars.Both

            dgvMatches.Refresh()

 

        Catch ex As Exception

 

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

 

        End Try

 

    End Sub

Next up is the button click event handler used to evoke the Geocoding web service; the code is annotated to describe what is going on within the event handler. 
 

    ''' <summary>

    ''' Click event handler used to evoke

    ''' the web service and to geocode the

    ''' physical address passed to that

    ''' service

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub btnGeocode_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs)Handles btnGeocode.Click

 

        ' make sure there is an address

        ' to geocode

        If txtSearchAddress.Text = String.Empty Then

            MessageBox.Show("Invalid search address.""Error")

            Return

        End If

 

        Try

 

            ' instance the geocoder service

            Dim gcAddress As New us.geocoder.rpc.GeoCode_Service()

 

            ' the event handler for completion of the

            ' geocoding does the work of displaying the 

            ' results the site offers alternative

            ' methods for viewing the geocoding results

            AddHandler gcAddress.geocode_addressCompleted, _AddressOf GetLatLong

 

            ' call the asynchronous version of the geocoder

            gcAddress.geocode_addressAsync(txtSearchAddress.Text)

 

            ' dispose of the service instance

            gcAddress.Dispose()

 

 

        Catch ex As Exception

 

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

 

        End Try

 

    End Sub

The Exit button event handler is described in the next section; this code merely terminates the application.
 

    ''' <summary>

    ''' Exit the Application

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub btnExit_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs)Handles btnExit.Click

 

        Application.Exit()

 

    End Sub

The last bit of code contained in the application is used open the Geocoded coordinates returned from the service into a running instance of Yahoo Maps. The approach here is simply to format a query string using the values returned from the service.
 

    ''' <summary>

    ''' Open a Yahoo! Map pointing at the location as

    ''' plotting using the latitude and longitude

    ''' recovered from the service.

    ''' Note:  There will likely be some error on

    ''' the position as this tool returns an

    ''' estimated lat/lon with no guarantee of

    ''' accuracy

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub dgvMatches_DoubleClick(ByVal sender As System.Object, _ByVal e AsSystem.EventArgs) Handles dgvMatches.DoubleClick

 

        ' map the location on a double click

 

        ' get the lat and long from the selected row

        Dim strLat As String = _

        dgvMatches.SelectedRows(0).Cells(4).Value.ToString()

 

        Dim strLon As String = _

        dgvMatches.SelectedRows(0).Cells(5).Value.ToString()

 

        ' launch Internet Explorer and fill in the lat and

        ' long values url's argument list

        System.Diagnostics.Process.Start("iexplore.exe", _"http://maps.yahoo.com/#mvt=m&lat=" + strLat + _"&lon=" + strLon + "&mag=3&q1=" + strLat + _"%2C%20" + strLon)

 

    End Sub

Summary.

This application was provided as an example of how one might take advantage of the Geocoder.us Address Geocoding service. This service is free for non-commercial use. If one were required to geocode a collection of addresses yet lacked access to some of the available third party tools (such as the ESRI product line), this service could be invaluable. The service mentioned in this article is also capable of Geocoding road intersections which could also be very useful.


Similar Articles