Using Google Maps with Visual Basic 2010

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

Getting lost is an unfortunate habit for me. My mind is always somewhere else, and before I know it, I have skipped a Stop sign… or two… My wife always wants to drive, because she always knows where to go and gets just as frustrated as I get when I am lost – but for other reasons… I am not blessed with a natural compass. I have to rely on maps, Google maps. This article will demonstrate how to use Google maps in your VB desktop application.

Google Documentation & Samples

I should say that I am somewhat disappointed with the lack of documentation. I am not saying that there isn’t documentation for Google’s libraries, I am saying that the way the documentation is structured is not as good as Microsoft’s MSDN, or Facebook’s documentation. That is a bit disappointing. Perhaps I am too spoilt with Microsoft’s huge reference section, that nothing else can compare to it.

I struggled immensely to find the proper details of all of Google’s classes and methods of those classes.

The samples I found to be a bit lacking. Whenever I explore new programming
territories, I always like to imagine myself being a beginner programmer. Perhaps it is the teacher in me; or perhaps it is the long road I had to walk, that causes this mindset. Anyway, from a beginner’s perspective, I’d say that the samples provided about Google’s inner workings by most places are way too advanced. Yes, there are some complicated things that need to be demonstrated, but being a “beginner” I honestly didn’t know where to start, or where to add which class. That was tough to figure out. All samples floating around on the net are solely on C#, which I think is quite unfair, hence this VB.NET article 🙂

Luckily, I came across this codeplex sample, which was really worth my while! It was the most complete example I have found, and it works 100%. In our project, we will use some of this project’s output files. I am not saying that we will just make a VB.NET version of this article, we will only utilize what is needed and make our own unique sample, with its help.

Our Project

The purpose of our project is to quickly find a location on a Google map. In this project we will not go too overboard with unnecessary methods that we might not need.

Open Visual Studio 2010, and start a new Windows Forms VB project. Name it
anything you like. My sample (that I am including), is named FindMeQuick. Add the following objects to the form, with their associated properties :

Control Property Setting
Form1 Name frmFMQ
  Size 880, 606
  Text Find Me Quick
  WindowState Maximized
Panel Name Panel1
  Dock Top
  Location 0, 0
Panel Name Panel2
  Dock Left
  Location 0, 60
Panel Name Panel3
  Dock Fill
Label Location 12, 5 ( Inside Panel1 )
  Text Address to Search
TextBox Name txtSearch
  Location 111, 3 ( Inside Panel 1 )
  Size 398, 20
TrackBar Name tbZoom
  LargeChange 2
  Location 515, 3 ( Inside Panel 1 )
  Maximum 20
  Size 264, 45
  Value 15
Button Name btnSearch
  Location 785, 3 ( Inside Panel 1 )
  Text Search
Listview Name lvAddressDetails
  Columns MainAddress

Latitude

Longitude

  Dock Fill
  Location Inside Panel 2
  View Details
ElementHost Name ehImageHost
  Dock Fill
  Location Inside Panel 3

Coding

First, download the codeplex project I mentioned earlier. Unzip the downloaded project – note that this project is based on the .NET Framework 3.5. Open the solution, and Run it or Build it. This will produce a library file called Google.Api.Maps.Service.dll inside the src\Google.Api.Maps.Service\bin\Debug folder. We should now set References to this project’s output inside our project.

Setting References

Apart from setting a reference to Google.Api.Maps.Service.dll, we also need to set other References, because we will be working with WPF controls inside our Windows Forms application. Let us set the following references:

Reference Tab Item
Google.Api.Maps.Service.dll Browse [Download Location]\src\Google.Api.Maps.Service\bin\Debug
PresentationCore .NET PresentationCore
PresentationFramework .NET PresentationFramework
System.XAML .NET System.XAML
WindowsBase .NET WindowsBase

We have set the reference to the GoogleMaps project so that we can use its functionality from inside our program. The Windows Presentation Foundation references, we need in order to utilize WPF features and controls inside our Windows Forms application.

Namespaces

Add the following Imports statements:

Imports Google.Api.Maps.Service.Geocoding ‘GeoCoding functionalities
Imports Google.Api.Maps.Service.StaticMaps ‘Map methods
Imports System.Windows.Media.Imaging ‘Added reference to PresentationCore for WPF image capabilities

The first two lines ensure that we are able to make use of the Google Library’s methods. The third line imports the Imaging functions present inside System.Windows. These Imaging functions are much more powerful than the Imaging functions inside System.Drawing; and that is probably the biggest reason why I opted to make use of it as well.

Searching for an Address

When searching for an address location, or route on a Google Map, we have to
tap into the Google
Geocoding API
. The purpose of this API is to convert a written address into a geographic coordinate. A geographic coordinate is expressed in Latitude and Longitude. Add the
following for your Search button:

  Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click

     Try
       Dim fmqRequest = New GeocodingRequest() 'Request geographical info
       fmqRequest.Address = txtSearch.Text 'Address that needs to be converted to geographic coordinates
       fmqRequest.Sensor = "false" 'No built in location sensor

       Dim fmqResponse = GeocodingService.GetResponse(fmqRequest) 'Get response from request

       If fmqResponse.Status = ServiceResponse.Ok Then 'Everything OK, add to Listview

         lvAddressDetails.Items.Add(fmqResponse.Results.Single().FormattedAddress.ToString) 'Main address
         lvAddressDetails.Items(0).SubItems.Add(fmqResponse.Results.Single().Geometry.Location.Latitude) 'Latitude
         lvAddressDetails.Items(0).SubItems.Add(fmqResponse.Results.Single().Geometry.Location.Longitude) 'Longitude


       End If

     Catch ex As System.InvalidOperationException
       MessageBox.Show("Please enter Town / Suburb / City with Street Address") 'Improper address
     End Try
   End Sub

In this sub, we created a GeocodingRequest object, and set its Address property to the typed in address. We then created a Response object to determine whether or not the supplied address was valid thus making the request valid. If the response was fine, we add the address details as well as the latitude position and longitude position in the ListView. ServiceResponse is an enum that we quickly have to add. This enum contains all possible response values from the GeocodingRequest object. We also needed to catch the InvalidOperation Exception, which usually occurs if an address hasn’t been entered completely. We do not need to use:

Catch ex As Exception

Because that will be classified as Pokemon Exception Handling. It is actually common-practice among some programmers I know, and it is so wrong! It is actually quite unprofessional in my opinion. Cater for specific errors and plan for them accordingly without being lazy.

Let us add the enum now:

  Private Enum ServiceResponse
     Unknown 'Unknown response
     Ok ' Everything is fine
     InvalidRequest 'Address requested was improperly formatted
     ZeroResults 'No results to return, possibly a non-existant address
     OverQueryLimit 'Too many request on a given day
     RequestDenied 'Reques denied
   End Enum

Getting the Map

Now that we have found the coordinates to the entered address, we need to display the map according to our coordinates. The best place to add this functionality is inside the ListView’s SelectedIndexChanged event. Let us add that now:

  Private Sub lvAddressDetails_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvAddressDetails.SelectedIndexChanged

     If lvAddressDetails.SelectedIndices Is Nothing Then 'Nothing selected
       Return
     End If

     Dim fmqLocation As New GeoPos 'Latitude and Longitude Values
     fmqLocation.Latitude = lvAddressDetails.SelectedItems(0).SubItems(1).Text 'Set Latitude property
     fmqLocation.Longitude = lvAddressDetails.SelectedItems(0).SubItems(2).Text 'Set Longitude property

     Dim fmqMap = New StaticMap() 'New map object

     fmqMap.Center = fmqLocation.Latitude.ToString() & "," _
       & Convert.ToString(fmqLocation.Longitude) 'Center-focus the map to your desired location
     fmqMap.Zoom = tbZoom.Value.ToString("0") 'Zoom percentage
     fmqMap.Size = "250x250" 'Size of map
     fmqMap.Markers = fmqMap.Center
     fmqMap.MapType = "Roadmap" 'Can be Roadmap, Satelite, Terrain, Hybrid
     fmqMap.Sensor = "false" 'No built in location sensor

     Dim mpMap As New BitmapImage() 'added reference to WindowsBase and System.XAML
     mpMap.BeginInit()
     mpMap.CacheOption = BitmapCacheOption.OnDemand 'Cahce only when needed
     mpMap.UriSource = fmqMap.ToUri() 'Source of map / image

     mpMap.EndInit()

     ehImageHost.Child = ehImage 'Set child control in element host
     ehImage.Source = mpMap 'Set Image source

   End Sub

A couple of things happen here, so I’ll break it down into smaller pieces. First, we determine a selection in the ListView. Based on this selection, we obtain a Latitude position and Longitude position to be used for the map. This happens via the GeoPos class, which only exposes the Latitude and Longitude properties. Feel free to add it to your project now, or later. Here is the code for GeoPos :

Public Class GeoPos

   Private Lng As Decimal 'Longitude Value
   Private Lat As Decimal 'Latitude Value

   Public Property Latitude() As Decimal 'Gets / Sets Latitude
     Get
       Return Lat
     End Get
     Set(ByVal value As Decimal)
       Lat = value
     End Set
   End Property

   Public Property Longitude() As Decimal 'Gets / Sets Longitude
     Get
       Return Lng
     End Get
     Set(ByVal value As Decimal)
       Lng = value
     End Set
   End Property

 End Class

We then create a StaticMap object and configure its settings, indicating what type of map we want (which can be Roadmap, Satellite, Terrain or Hybrid), what size the map should be and where its focus area should be focused.

Lastly, we create a BitmapImage object to display our map properly inside our WPF ElementHost‘s child object. You will notice that you need to add a declaration for the ehImage object:

  Private ehImage As System.Windows.Controls.Image = New System.Windows.Controls.Image() 'Added Element Host from WPF section in toolbox

That’s it! If you were to build and run your application now, you will see that it searches for your entered address and displays the map, based on your ListView selection.

Example

Figure 1Example

Conclusion

The purpose of this article was just to show how easy it can be to display Google maps in your application. You could use this project as a reference to learn from, or a framework to build upon further. I hope you have enjoyed this article, and that you won’t get lost (as much as I do) anymore. Till next time, cheers!

About the Author:

Hannes du Preez is a Microsoft MVP for Visual Basic for the fifth year in a row. He is a trainer at a South African-based company providing IT training in the Vaal Triangle. You could reach him at hannes [at] ncc-cla [dot] com

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read