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:
Imports GMap.NET
Imports GMap.NET.MapProviders
Imports GMap.NET.WindowsForms
In the Class
, I declare these variables:
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:
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
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
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 Northing
s and Easting
s values, then convert it to Coords and pass it as a Point
to GMap
s:
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
Me.gMap.Manager.Mode = AccessMode.ServerAndCache
Me.gMap.Overlays.Add(New GMapOverlay)
Me.gMap.HoldInvalidation = True
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
" - " & 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
gMap.Overlays(0).Markers(II - 1).ToolTipMode = _
MarkerTooltipMode.Always
gMap.Overlays(0).Markers(II - 1).IsVisible = True
Next row
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
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 Northing
s and Easting
s 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