Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

GMaps Control Simplified in VB.NET

4.83/5 (7 votes)
16 Feb 2018CPOL2 min read 33.4K  
GMaps Control Simplified in VB.NET

Introduction

The original code was done in VS2012, but as the language changed in the later versions, I reworked the code to work in VS2017.

Background

You can read the original tutorial here.

Also - as I live in the UK, I am using a Dataset containing UK Postcodes which can be obtained for free from the Codepoint Open Site.

This only worked for the UK - excluding Northern Ireland. This allows me to get a CSV data file containing Northings and Eastings values. I imported this into a table in SQL (SQL Server or MYSQL - does not matter. My example uses SQL Server Express).

First, follow the steps in the tutorial to download and install/include (Setting up...) this DLL in your project.

Create a Windows Form and then add the Control to the new Form. For simplification, I also added a Text Box which I use for entering a UK Postcode.

Using the Code

So this is how this is going to work. I enter a Postcode into a Textbox. I run a query to the SQL Database Table to pick up the value of Northings and Eastings, which then is converted in VB.NET to a Latitude and Longitude coord, which is then passed to a MapProvider and GMap control, and you will then see the Location as a Marker on your Map.

So here is the code.

I first load the Map in the Form Load as a Default Map.

Make sure your code page has these 3 Imports statements:

VB.NET
Imports GMap.NET
Imports GMap.NET.MapProviders
Imports GMap.NET.WindowsForms

In the Class, I declare these variables:

VB.NET
Public Class frmMap
    Dim dsData As DataSet
    Dim cProc As clsProcess
    Dim cGeo As os_latlong.LatLonConversions

    Dim sEA As Double
    Dim sNO As Double
    Dim sLon As String
    Dim sLat As String

In the Form Load, I have the following Default Map Load code:

VB.NET
Private Sub frmMap_Load(sender As Object, e As EventArgs) Handles Me.Load
        Dim sSQL As String = ""
        Dim sInfo As String = ""
        Dim II As Int32 = 0
        Try

            tbZoom.Maximum = 18
            tbZoom.Minimum = 0
            tbZoom.TickFrequency = 2
            tbZoom.LargeChange = 2
            tbZoom.SmallChange = 1

            'Startup the Map Control Default=========================='

            GMapProvider.WebProxy = Net.WebRequest.DefaultWebProxy
            GMapProvider.WebProxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials

            If My.Computer.Network.Ping("www.google.com", 1000) = True Then
                gMap.Manager.Mode = AccessMode.ServerAndCache

                'Some other Map Providers if you wish========='

                'CloudMadeMapProvider - does not work'
                'GoogleMapProvider - Works OK'
                'OpenCycleMapProvider - Works OK'
                'OpenStreetMapProvider - does not work'
                'WikiMapiaMapProvider'
                'YahooMapProvider'


                'OpenStreetMap does not work!======'
                'gMap.MapProvider = MapProviders.OpenCycleMapProvider.Instance'

                'Bing Maps works!'
                'gMap.MapProvider = MapProviders.BingMapProvider.Instance'
                'Google Maps works - reportedly a bit slow!!'
                gMap.MapProvider = MapProviders.GoogleMapProvider.Instance

                With Me.gMap
                    .Position = New GMap.NET.PointLatLng(51.51, -0.14)
                    .SetPositionByKeywords("London")
                    .ZoomAndCenterMarkers(CType(vbNull, String))
                    .Zoom = 10
                    .ShowCenter = True
                End With
                gMap.Refresh()

            Else
                MessageBox.Show("There is no Internet Connection. _
                    This is needed to load the Maps from Google. Please connect to the Network!", _
                    "Error loading Map Data!", MessageBoxButtons.OK)
                Exit Try
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error loading data!", MessageBoxButtons.OK)
        End Try

    End Sub

Now for the code where I enter a Postcode into a Text Box, click a Button, run the SQL Query to get the Northings and Eastings values, then convert it to Coords and pass it as a Point to GMaps:

VB.NET
Private Sub cmdxGo_Click(sender As Object, e As EventArgs) Handles cmdxGo.Click
        Dim sSQL As String = ""
        Dim sInfo As String = ""
        Dim II As Int32 = 0
        Try
            gMap.Overlays.Clear()
            gsPostcode = Me.TextBox2.Text
            sSQL = "Select Easting, Northing from [UKMaps].[dbo].[Postcodes] where PC2 = '" & _
                    gsPostcode & "'"

            dsData = New DataSet
            cProc = New clsProcess
            giDB = clsEnums.giDB.iPostcode
            cProc.GetData(sSQL, dsData)
            cProc = Nothing
            If dsData.Tables(0).Rows.Count > 0 Then
                sEA = CDbl(dsData.Tables(0).Rows(0).Item(0))
                sNO = CDbl(dsData.Tables(0).Rows(0).Item(1))

                sLat = os_latlong.LatLonConversions.ConvertOSToLatLon(sEA, sNO).Latitude.ToString
                sLon = os_latlong.LatLonConversions.ConvertOSToLatLon(sEA, sNO).Longitude.ToString

                Me.lblGeoDatax.Text = "East = " & sEA & " // Lat = " & sLat & vbNewLine _
                                          & "North = " & sNO & " // Lon = " & sLon


                'Plot it on the Map Control======'
                Me.gMap.Manager.Mode = AccessMode.ServerAndCache
                Me.gMap.Overlays.Add(New GMapOverlay)
                Me.gMap.HoldInvalidation = True
               'ADD THE MARKERS========='

                For Each row As DataRow In dsData.Tables(0).Rows
                    II += 1
                    sEA = CDbl(dsData.Tables(0).Rows(II - 1).Item(0))
                    sNO = CDbl(dsData.Tables(0).Rows(II - 1).Item(1))

                    sLat = os_latlong.LatLonConversions.ConvertOSToLatLon(sEA, sNO).Latitude.ToString
                    sLon = os_latlong.LatLonConversions.ConvertOSToLatLon(sEA, sNO).Longitude.ToString
                    'sInfo = row.Item(0).ToString & ": " & row.Item(2).ToString & _
                             " - " & Format(row.Item(3), "c")'
                    sInfo = "My Fancy Places"
                    gMap.Overlays(0).Markers.Add(New Markers.GMarkerGoogle_
                    (New PointLatLng(CDbl(sLat), CDbl(sLon)), Markers.GMarkerGoogleType.red))
                    gMap.Overlays(0).Markers(II - 1).ToolTipText = _
                                       sInfo ' Acts as a Label to display Data in'
                    gMap.Overlays(0).Markers(II - 1).ToolTipMode = _
                      MarkerTooltipMode.Always 'Shows data Label with info - always visible on the map'
                    gMap.Overlays(0).Markers(II - 1).IsVisible = True
                Next row


                'REFRESH THE MAP'
                With Me.gMap
                    .Overlays(0).IsVisibile = True
                    .Zoom = 10
                    .ShowCenter = True
                    .ZoomAndCenterMarkers(CType(vbNull, String))
                    .Refresh()
                End With

            Else
                Me.lblGeoDatax.Text = "Postcode not found!"
            End If


        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error loading data!", MessageBoxButtons.OK)
        End Try
    End Sub

Image 1

This works well if you have a Table with UK Customers containing Postcodes and you want to then join the Postcodes Table on Postcodes to get the Northings and Eastings values, and plot them on a Map with markers of different colours. I just used Red ones for this example. You could add Tooltip so you can only see Info when you hover over the marker rather than plaster Info labels all over your Map.

I exclude the code where I connect to a SQL Database and extract the data to create a Dataset. You should be able to do this by now, otherwise you can do some digging to see how to create a ADO.NET Dataset (System.Data.OLEDB). I hope this tutorial works for you.

Points of Interest

You can also use this control to create Routes, with a Start Point and End Point, using the Google Maps Provides, and it will tell you the distance to travel with the time it will take.

On the down side, you cannot use this for Heat maps though.

History

  • 16th February, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)