Page 1 Page 2




First Published 6 Dec 2022                                     Last Updated 7 Dec 2022                                            Difficulty level :   Moderate

Section Links (this page):
          Example App
          VBA Code
          Download
          Related items/apps
          Related articles/code
          Useful links
          Summary
          Feedback


This is the third in a series of articles about annotating downloaded maps in Access

The first part of this article demonstrated several of the different ways that online maps can be modified by adding additional layers.

The second part discussed how the large amounts of data used with complex maps is managed using a combination of encoding and sampling.

This third article will be used to put all this information together including how the URLs are built up in code.
Explanations will be done with reference to an example app supplied with all code.



1.   Example app                                                                                                                             Return To Top

      The example app includes all the features described in this series of articles and is supplied with all required data for a range of 15 UK postcodes
      You will need a free Google Maps API key in order to use the app


      Splash form

      The application opens to a small splash form which automatically closes after a couple of seconds

SplashForm

      API form

      The first time you use the application, the API Info form will appear next:

APIForm

      If you already have a Google Maps API key for the 3 specified APIs, Static Maps, Places & Geocoding, enter it now
      Otherwise go to the Google Map Platform webpage, obtain an API key, copy and paste it into the form then click Update

      NOTE: A valid Google Maps API key has 39 characters starting with AIzaSy

      Now close the form. The Main form opens.


      Main form

MainForm

      If you have previously entered a valid API key, the app will open this form directly from the splash form

      The main form opens with two downloaded maps (roadmap/satellite) for the default postcode SE1 7PB.
      This is an area of Central London which includes the London Eye tourist attraction

      Click the Start Update button to cycle through each of the 15 postocdes in a random order using a timer event.
      Every 5 seconds two new maps will be downloaded for the new postcode

      OPTIONAL: If you want to use the currently selected postcode to create your own maps, click Pause Update and then check Use This Postcode

      Click one of the map buttons: Annotate Browser Maps or Annotate Static Maps


      Web Browser form

      Select from the options to build a map. As you do so, the information is updated in the URL textbox
      The total number of characters is displayed for information.

      When you have completed all required items, click the Add API Key button
      The Show Browser button is now enabled. Click to create a map in the browser control. This is done using the Google Static Maps API

      An example address is also displayed for the selected postcode. This is generated using the Geocoding API (see later for more details)

WebBrowser1

      If you select Satellite or Hybrid as your map type, the Scale item appears with default value 1. Change to 2 for twice the resolution

WebBrowser2

      NOTE:
      The API key shown in the above screenshots is a dummy value used here for display purposes. It is NOT a valid API key and will not work!

      You can also select one or more of the optional items to add additional layers to your map

WebBrowser3

      However, if you exceed the character limit (2083) for the browser control, this message wil be displayed

URLLimitExceeded


      Downloaded Map Form

      This is very similar to the web browser form but with additional options.

      As before, select from the options to build a map. As you do so, the information is updated in the URL textbox
      The total number of characters is displayed.

      When you have completed all required items, click the Add API Key button then click Generate Map

StaticMaps1
      The map is saved with the file name map.png in the same folder as the example app
      Each time a new map is created, this file is updated automatically

StaticMaps2
      You can create more complex map layers without issues as the number of characters in the URL is no longer subject to the IE browser control limit.

      The map shown below has a URL of almost 15500 characters

LongURL
      However it is still limited by the Google Maps URL limit which is currently 16384 (16K) characters

      Due to the use of data encoding and data sampling, it is unlikely you will be able to build a URL which exceeds this limit


      Nearby Places

      Using the Static Maps form, complete all required items then tick the Circle checkbox and choose from the circle options. Next tick the Nearby Places checkbox.
      The map type will change to roadmap and several other options will be automatically over-ridden for this purpose.

      A circle will be drawn with the specified radius and up to 20 nearby places of interest will be displayed with a yellow marker within the circle.
      The places will also be displayed in a listbox in alphabetical order

NearbyPlaces

      The list of places is generated using the Google Places API.
      It is downloaded as a JSON file, analysed by the example app and the places data is stored (temporarily) in the table tblNearbyPlaces

      In this example app, the places can be any type of location designated as a place of interest
      However Google designates almost 100 different place types such as bank, restaurant, government building etc.

      In my commercial app, UK Postal Address Finder, you can restrict the list to a specified place type only.
      For example, this shows all the restaurants within 150 metres of the London Eye (postcode SE1 7PB)

NearbyPlaces2
      Double click on any item in the list to open the place detail form. This provides detailed information about the selected location including:
      •   address, phone and website URL
      •   photographs
      •   customer reviews

NearbyPlaceDetail
      In addition, the map can be zoomed in/out and nudged left/right/up/down
      A new map is generated after each change made



2.   VBA Code                                                                                                                                   Return To Top

      Much of the code used in this example app has already been described in these related articles:

      a)   The first part of this series of articles: Annotate Google Maps - Part 1

      b)   Fix Google maps display issues in Access web browser control

      c)   Encoded Map Path Co-ordinates

      d)   Missing Trigonometric Functions

      The following code is also used throughout the application

      e)   Get Address using Geocoding

            This retrieves a typical address for the selected postcode location using the Geocoding API

Private Function GetAddress()

'---------------------------------------------------------------------------------------
' Function               : GetAddress
' DateTime             : 12/10/2018
' Author                  : Colin Riddington
' Company             : Mendip Data Systems
' Purpose               : Uses reverse geocoding to get address from postcode
' Credits                 : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------------------------------------

On Error GoTo Err_Handler

      Dim strAddress As String

      sngLat = Nz(DLookup("Latitude", "Postcodes", "Postcode='" & Me.cboLocation & "'"), 100)
      sngLong = Nz(DLookup("Longitude", "Postcodes", "Postcode='" & Me.cboLocation & "'"), 100)

      'build url
      strURL = GetGoogleGeocodingBase() & "?latlng=" & sngLat & "," & sngLong & " &key=" & GetGoogleMapsAPIKey()

      strPath = Application.CurrentProject.Path & "\JSON\GeolocationAddress.json"

GetJSON:
      'setup the request and authorization
      Set http = New MSXML2.XMLHTTP60

      http.Open "GET", strURL, False
      http.Send ""

     'save to file
      Set stm = CreateObject("ADODB.Stream")
      stm.type = 2      ' acTypeText
      stm.Open

      stm.WriteText http.responseText
      stm.SaveToFile strPath, 2       'adSaveCreateOverWrite

ReadJSON:
     ' Read .json file
      Set JsonTS = fso.OpenTextFile(strPath, ForReading, False, -1)
      strJSON = JsonTS.ReadAll
      ' Debug.Print strJSON
      JsonTS.Close

      'get first formatted address location from JSON file
      strAddress = Mid(strJSON, InStr(strJSON, "formatted_address") + 22, 100)
      ' Debug.Print strAddress

      If strAddress Like "*REQUEST_DENIED*" Then
            FormattedMsgBox "There is a problem with your API key" & _
                  "@Please check your API key is correct and try again @", vbCritical, "API key is NOT valid"
            DoCmd.Close acForm, Me.Name
            DoCmd.OpenForm "frmAPI"
      Else
            strAddress = Left(strAddress, InStr(strAddress, """") - 1)
            'Debug.Print strAddress
            Me.txtAddress = strAddress
      End If

Exit_Handler:
      Exit Function

Err_Handler:
      FormattedMsgBox "Error " & Err.Number & " in GetAddress procedure : " & _
            "@" & Err.Description & " @", vbCritical, "Program error"
      Resume Exit_Handler

End Function



            The JSON output is saved in the file GeolocationAddress.json. It is then analysed and the first recognised address is shown on the map forms

      f)   Draw circles around a specified location

            This uses 2 procedures:
            •   GMapCircle - creates the location data points for the circle
            •   PopulateMapCircleData - saves the data to a temporary table

Function GMapCircle(Lat, Lng, Rad, Detail)

'---------------------------------------------------------------------------------------
' Function               : GMapCircle
' DateTime             : 12/10/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Used to create location data points to draw a circle
' Credits                  : https//isladogs.co.uk
'                                : modified version of code written in PHP by Oliver Beattie / Josh McDonald
'                                : http://jomacinc.com/map-radius/
' Updated               : Nov 2021
'---------------------------------------------------------

      'Set detail = 10 to get records every 10 degrees around circle
      'Detail = 10

      Dim R As Long, D As Single
      Dim brng As Double
      Dim Points() As Variant
      Dim arrValues As Variant
      Dim pLat As Double, pLng As Double

      R = 6371000 'earth radius in km
      'Rad = radius of circle (metres)

      Lat = (Lat * Pi) / 180
      Lng = (Lng * Pi) / 180
      D = Rad / R 'scaling factor

      I = 0

      'populate table with circle points
      Set RST = CurrentDb.OpenRecordset("tblMapCircle", dbOpenDynaset)

      With RST
            For I = 0 To 360 Step Detail
                  brng = I * Pi / 180
                  pLat = ASin((Sin(Lat) * Cos(D)) + (Cos(Lat) * Sin(D) * Cos(brng)))
                  pLng = ((Lng + Atn2(Sin(brng) * Sin(D) * Cos(Lat), Cos(D) - Sin(Lat) * Sin(pLat))) * 180) / Pi
                  pLat = (pLat * 180) / Pi
                  'Debug.Print i, pLat, pLng
                  .AddNew

                  !Bearing = I
                  !Latitude = pLat
                  !Longitude = pLng
                  .Update
            Next

            .Close

      End With

      Set RST = Nothing

End Function

'===============================================

Private Sub PopulateMapCircleData()

'---------------------------------------------------------------------------------------
' Procedure            : PopulateMapCircleData
' DateTime             : 12/10/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Used to save circle location data points to a table
' Credits                  : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------

On Error GoTo Err_Handler

      Dim intDetail As Integer

      intDetail = 10 'bearing every 10 degrees

      'get lat / long data for circle points & add to tblMapCircle
      GMapCircle sngLat, sngLong, lngRad, intDetail

      'multiply values by 10000
      CurrentDb.Execute "UPDATE tblMapCircle SET tblMapCircle.LatE5 = 100000*[Latitude], tblMapCircle.LongE5 = 100000*[Longitude];"

      'get previous values and append to tblMapCirclePrevLatLong
      CurrentDb.Execute "qryAppendMapCirclePrevLatLong"

      'update first record where bearing = 0
     CurrentDb.Execute "UPDATE tblMapCirclePrevLatLong" & _
            " SET tblMapCirclePrevLatLong.PrevLatE5 = 0, tblMapCirclePrevLatLong.PrevLongE5 = 0" & _
            " WHERE (((tblMapCirclePrevLatLong.Bearing)=0));"

      'populate tblMapCircle from tblMapCirclePrevLatLong
      CurrentDb.Execute "UPDATE DISTINCTROW tblMapCircle INNER JOIN tblMapCirclePrevLatLong" & _
            " ON tblMapCircle.Bearing = tblMapCirclePrevLatLong.Bearing" & _
            " SET tblMapCircle.PrevLatE5 = [tblMapCirclePrevLatLong].[PrevLatE5]," & _
            " tblMapCircle.PrevLongE5 = [tblMapCirclePrevLatLong].[PrevLongE5];"

      'populate change in latitude & longitude between records
      CurrentDb.Execute "UPDATE tblMapCircle" & _
            " SET tblMapCircle.LatChange = [LatE5]-[PrevLatE5], tblMapCircle.LongChange = [LongE5]-[PrevLongE5];"

      'encode each record using EncGeoCode function
      CurrentDb.Execute "UPDATE tblMapCircle" & _
            " SET tblMapCircle.EncLat = EncGeoCode([LatChange]), tblMapCircle.EncLong = EncGeoCode([LongChange])," & _
            " tblMapCircle.EncPoint = EncGeoCode([LatChange]) & EncGeoCode([LongChange]);"

Exit_Handler:
      Exit Sub

Err_Handler:
      FormattedMsgBox "Error " & Err.Number & " in PopulateMapCircleData procedure : " & _
            "@" & Err.Description & " @", vbCritical, "Program error"
      Resume Exit_Handler

End Sub



      g)   NearbyPlacesImport

            This is used to import a list of places of interest within a specified radius of the selected location

Private Sub NearbyPlacesImport()

'---------------------------------------------------------------------------------------
' Procedure            : NearbyPlacesImport
' DateTime             : 22/10/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Used to import JSON data for places of interest within a specified radius of the selected location
' Credits                  : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------

On Error GoTo Err_Handler

      If GetInternetConnectedState = False Then
            If blnSilent = False Then
                  blnSilent = True
                  FormattedMsgBox "You are not currently connected to the Internet " & _
                        "@Nearby places & location map data cannot be downloaded " & vbCrLf & vbCrLf & _
                        "Please try again later @", vbCritical, "No Internet connection"
            End If
            Exit Sub
      Else
            blnSilent = False
      End If

      Dim Results As Variant, geometry As Variant, location As Variant, types As Variant
      Dim photos As Variant, arrValues As Variant, rst As DAO.Recordset

      'Google Places API
      lngRadius = Nz(Me.cboRad, 500) 'default = 500 metres
      sngLat = Nz(DLookup("Latitude", "Postcodes", "Postcode='" & Me.cboLocation & "'"), 100)
      sngLong = Nz(DLookup("Longitude", "Postcodes", "Postcode='" & Me.cboLocation & "'"), 100)

      'check for required information
      If sngLat = 100 Or sngLong = 100 Then
            FormattedMsgBox "The nearby places search cannot be done " & _
                  "@Required geolocation information is missing @", vbCritical, "Cannot run nearby places search"
            Exit Sub
      End If

      If GetGoogleMapsAPIKey = "" Then
            FormattedMsgBox "The nearby places search cannot be done " & _
                  "@Google Places API key information is missing @", vbCritical, "Cannot run nearby places search"
            Exit Sub
      End If

      strPlaces = GetGooglePlacesBase & "?location=" & sngLat & "," & sngLong & "" & _
            "&radius=" & lngRadius & "&key=" & GetGoogleMapsAPIKey

      strPath = Application.CurrentProject.Path & "\JSON\NearbyPlacesImport.json"
      ' Debug.Print strPlaces

GetJSON:
      'setup the request and authorization
      Set http = New MSXML2.XMLHTTP60

      http.Open "GET", strPlaces, False
      http.Send ""

      'save to file
      Set stm = CreateObject("ADODB.Stream")
      stm.type = 2       ' acTypeText
      stm.Open

      stm.WriteText http.responseText
      stm.SaveToFile strPath, 2 'adSaveCreateOverWrite

      'End of Online section

'====================================

ReadJSON:
      ' Read .json file
      Set JsonTS = fso.OpenTextFile(strPath, ForReading, False, -1)
      strJSON = JsonTS.ReadAll

      'Debug.Print strJSON       JsonTS.Close

      'check for empty search results or other errors
      If Not strJSON Like "*" & """status"" : ""OK""" & "*" Then
            If strJSON Like "*" & "ZERO_RESULTS" & "*" Then
                  FormattedMsgBox "There are no results for this nearby places search " & _
                        "@Postcode = " & String(2, " ") & "'" & strPostcode & "'" & vbCrLf & _
                        "Radius = " & String(7, " ") & "'" & lngRadius & "'" & vbCrLf & _
                        "Type = " & String(10, " ") & "'" & strSearchType & "'" & vbCrLf & _
                        "Keyword = " & String(4, " ") & "'" & strKeyword & "'" & vbCrLf & vbCrLf & _
                        "Please try again with different search criteria @", vbExclamation, "No matching search results"
                  Me.Requery
                  DoEvents
            Exit Sub
      Else
            FormattedMsgBox "Unknown error for this nearby places search " & _
                  "@Postcode = " & String(2, " ") & "'" & strPostcode & "'" & vbCrLf & _
                  "Radius = " & String(7, " ") & "'" & lngRadius & "'" & vbCrLf & _
                  "Type = " & String(10, " ") & "'" & strSearchType & "'" & vbCrLf & _
                  "Keyword = " & String(4, " ") & "'" & strKeyword & "'" & vbCrLf & vbCrLf & _
                  "Please try again with different search criteria @", vbExclamation, "No matching search results"
                  Exit Sub
            End If
      End If

'============================================

RemoveUnwantedSpaces:
      'remove unwanted spaces around brackets
      ' Debug.Print "LenStart " & Len(strJSON)

      Dim LS As Long, LE As Long

      LS = Len(strJSON)

      'strJSON = Replace(Replace(strJSON, "[ {", "[{"), "} ]", "}]")
      strJSON = Replace(Replace(strJSON, "[ ", "["), " ]", "]")
      strJSON = Replace(Replace(strJSON, "{ ", "{"), " }", "}")
      strJSON = Replace(Replace(strJSON, """ ", """"), " """, """")
      strJSON = Replace(Replace(strJSON, ", ", ","), " ,", ",")
      strJSON = Replace(strJSON, ": ", ": ")
      LE = Len(strJSON)

      If LE < LS Then GoTo RemoveUnwantedSpaces

      ' Debug.Print "LenEnd " & Len(strJSON)

      'now that unwanted spaces have been removed, line feeds can also be removed
      strJSON = Replace(Replace(strJSON, vbLf, ""), vbCr, "")

      'add missing array brackets
      strJSON = Replace(strJSON, """geometry"": {", """geometry"": [{")
      strJSON = Replace(strJSON, ",""icon""", "],""icon""")
      strJSON = Replace(strJSON, """location"": {", """location"": [{")
      strJSON = Replace(strJSON, "},""viewport""", "}],""viewport""")

      ' Debug.Print "LenFinal " & Len(strJSON)

      strJSON = Trim(strJSON)
      'Debug.Print strJSON

'============================================

      'write to table tblNearbyPlaces
      Set rst = CurrentDb.OpenRecordset("tblNearbyPlaces", dbOpenDynaset, dbSeeChanges)
      Set JSON = modJsonConverter.ParseJSON(strJSON)
      'Debug.Print JSON

      icount = 65 'ASCII code for capital A

      strPostcode = Replace(Me.cboLocation, " ", "+")

      With rst
            For Each Results In JSON("results")
                  For Each geometry In Results("geometry")
                        For Each location In geometry("location")
                              For Each types In Results("types")
                                    For Each photos In Results("photos")
                                          .AddNew
                                          'ID = autonumber PK field
                                          !Postcode = strPostcode
                                          !SearchDate = Now()
                                          !Radius = lngRadius
                                          !SearchType = strSearchType
                                          !Keyword = strKeyword
                                          !PlaceName = Results("name")
                                          !PlaceMarker = Chr(icount)       'assign letter for map marker
                                          !PlaceID = Results("place_id")
                                          !Longitude = location("lng")
                                          !Latitude = location("lat")
                                          !Vicinity = Results("vicinity")
                                          !Rating = Results("rating")
                                          !PhotoReference = photos("photo_reference")

                                          'get distance from postcode mean in metres
                                          !Distance = GetDistanceMetres(sngLat, sngLong, !Latitude, !Longitude)

                                         If !Distance > !Radius Then GoTo NextItem

                                          'types - subarray of values
                                          arrValues = Split(types, ",")

                                          For zCount = 0 To UBound(arrValues)
                                                ' Debug.Print zCount; UBound(arrValues)
                                                If strSelection = "" Then
                                                      strSelection = arrValues(zCount)
                                                Else
                                                      strSelection = strSelection & "," & arrValues(zCount)
                                                End If

                                                strSelection = Replace(strSelection, "_", " ")
                                                strSelection = Replace(strSelection, "establishment", "")
                                                'strSelection = Replace(strSelection, "point of interest", "")
                                                strSelection = Replace(strSelection, "locality", "")
                                                strSelection = Replace(strSelection, "political", "")
                                                strSelection = Replace(strSelection, ",,", ",")

                                                'remove trailing comma
                                                If Right(strSelection, 1) = "," Then strSelection = Left(strSelection, Len(strSelection) - 1)
                                                If strSelection = "" Then GoTo NextItem

                                          Next
                                   Next
                             Next
                             .Update
                       Next
                 Next

                 strSelection = ""
                 icount = icount + 1

NextItem:
           Next
           .Close
      End With

     ' Debug.Print strSelection

      Set rst = Nothing

      UpdateURL

Exit_Handler:
     Exit Sub

Err_Handler:
      If Err = 3420 Or Err = 13 Or Err = 92 Or Err = 94 Then Resume Next

      MsgBox "Error " & Err.Number & " in NearbyPlacesImport procedure : " & vbCrLf & _
      nbsp;     Err.Description, vbCritical, "Cannot create table"
      End If

      Resume Exit_Handler

End Sub



            The JSON output is saved in the file NearbyPlacesImport.json. It is then analysed and the data is stored in the table tblNearbyPlaces.
            The places data is also displayed in a listbox

            Similar code is used in the NearbyPlaceDetailJSONImport procedure with the additional data saved in the file NearbyPlaceDetailsImport.json.
            It is then analysed and the data is stored in the tables tblNearbyPlacePhotos and tblNearbyPlaceReviews.

      h)   UpdateURL

            After each selection is made on one of the map forms, an update procedure ensures the URL includes all the currently selected features.
            For example, this code is used to update the marker type required:

Private Sub UpdateMarker()

'---------------------------------------------------------------------------------------
' Procedure            : UpdateMarker
' DateTime             : 24/09/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Used to update the marker type in a map layer
' Credits                  : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------

      If chkMarker = True Then
            sngLat = DLookup("Latitude", "Postcodes", "Postcode='" & Me.cboLocation & "'")
           sngLong = DLookup("Longitude", "Postcodes", "Postcode='" & Me.cboLocation & "'")
           strMarker = "&markers=color:" & Me.cboMarkerColor & "|size:" & Me.cboMarkerSize & "|label:" & Me.cboLabel & "|" & sngLat & "," & sngLong
      Else
            strMarker = ""
     End If

      ' Debug.Print strMarker

      UpdateURL       'update the URL with strMarker value

End Sub


            Similar (but much more complex) code runs after other option changes: UpdateBoundary, UpdateCircle, UpdateLine and UpdateStyle

            At the end of each of these procedures , the UpdateURL procedure is then run.
            This combines the data from all selections together wth the API key to create the map URL.

Private Sub UpdateURL()

'---------------------------------------------------------------------------------------
' Procedure            : UpdateURL
' DateTime             : 24/09/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Combines the data from all map selections together wth the API key to create the map URL
' Credits                  : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------

On Error GoTo Err_Handler

      Dim strBase As String

      If Me.chkPlaces = True Then
            strBase = GetGooglePlacesBase
      Else
            strBase = GetGoogleStaticMapsBase
      End If

      'combine the Google base string with the saved values from the location, zoom, map size, map type & scale values
      ... and the marker, line, circle, boundary and style options (if used)
      Me.txtURL = strBase & "?" & strLoc & strZoom & strSize & strType & strScale & strMarker & strLine & strCircle & strBoundary & strStyle

      If blnAPIKey = True Then
      ...add the API key
            Me.txtURL = Me.txtURL & "&key=" & GetGoogleMapsAPIKey()
      End If

      Me.txtURL.Requery

      show the number of characters in the URL
      Me.txtChar = Len(Me.txtURL)

      If Me.txtChar > 0 Then
            cmdClear.enabled = True
            cmdCopy.enabled = True
      End If

      If strLoc <> "" And strZoom <> "" And strSize <> "" And strType <> "" Then
            'enable API Key button & optional items
            cmdKey.enabled = True
            Me.chkMarker.enabled = True
            Me.chkLine.enabled = True
            Me.chkCircle.enabled = True
            Me.chkBoundary.enabled = True
            Me.chkStyle.enabled = True
      End If

Exit_Handler:
      Exit Sub

Err_Handler:
      FormattedMsgBox "Error " & Err.Number & " in UpdateURL procedure : " & _
            "@" & Err.Description & " @", vbCritical, "Program error"
      Resume Exit_Handler

End Sub



      i)   Create map images
            When the GenerateMap button is clicked, the GetMapImage procedure is run

Private Sub GetMapImage()

'---------------------------------------------------------------------------------------
' Procedure            : GetMapImage
' DateTime             : 24/09/2018
' Author                  : Colin Riddington
' Company              : Mendip Data Systems
' Purpose                : Used to download a map image based on a specified location with selected properties and additional map layer criteria
' Credits                  : https//isladogs.co.uk
' Updated               : Nov 2021
'---------------------------------------------------------

On Error GoTo Err_Handler

      If GetInternetConnectedState = False Then
            If blnSilent = False Then
                  blnSilent = True
                  FormattedMsgBox "You are not currently connected to the Internet " & _
                        "@The location map cannot be updated @", vbCritical, "No Internet connection"
            End If

            ShowControls False, "M", "X"      'hide map controls
            ShowControls True, "C"       'show no internet message
            Exit Sub
      Else
            blnSilent = False
            ShowControls False, "C"       'hide no internet message
      End If

      Application.Echo False

      'set map path
      strFilePath = CurrentProject.Path & "\" & "map.png"

      'get URL for map including API key
      strURL = Me.txtURL
      ' Debug.Print strURL

      'Download map
      DownloadFilefromWeb strURL, strFilePath

      DoEvents
      If Len(strFilePath) <> 0 Then
            Me.Image0.Picture = strFilePath
            Me.Image0.Requery
      End If

      Application.Echo True

      ShowControls True, "M"       'show map controls

Exit_Handler:
      Exit Sub

Err_Handler:
      FormattedMsgBox "Error " & Err.Number & " in GetMapImage procedure : " & _
            "@" & Err.Description & " @", vbCritical, "Program error"
      Resume Exit_Handler

End Sub


            Similar code is used in the GetPlacesMapImage procedure



3.   Download                                                                                                                                   Return To Top

      The zip file contains the example app together with 3 JSON files in the JSON folder. Map image files are created as required

      Click to download:   View AnnotateGoogleMaps_v1.7     Approx 4 MB     (zipped)

      The example app is supplied as an ACCDB file with all code.
      It should work in all Access versions from 2010 onwards, both 32-bit and 64-bit

      NOTE:
      You are permitted to use the code in your own applications providing all copyright information is included in full and without any changes made.
      However, you must ask for permission from Mendip Data Systems to use any of this code in commercial applications.



4.   Other related items / example apps                                                                                     Return To Top

      The following apps use various geolocation features to generate maps. All are available elsewhere on this website:

a)   Get Geolocation from Photos   (FREE)

b)   Get Current Geolocation   (FREE)

c)   UK Postcode Address Lookup   (FREE)

d)   UK Postal Address Finder   (PAID)



5.   Related articles / code                                                                                                           Return To Top

The following articles also include code used in various parts of this application

a)   Encoded Map Path Co-ordinates

b)   Missing Trigonometric Functions

c)   Fix Google maps display issues in Access web browser control



6.   Useful links                                                                                                                               Return To Top

The following links will also help you get started on creating your own maps in Access:

a)   Google Static Maps API Developers Guides
      https://developers.google.com/maps/documentation/maps-static/start
      https://developers.google.com/maps/documentation/maps-static/styling

b)   Google Nearby Places API Developers Guide
      https://developers.google.com/maps/documentation/places/web-service/search-nearby

c)   IE browser URL character limit
      Maximum URL length is 2,083 characters in Internet Explorer (microsoft.com)
      What is the maximum length of a URL in different browsers? - Stack Overflow
      How long of a URL can Internet Explorer 9 take? - Stack Overflow



7.   Summary                                                                                                                                   Return To Top

The above article was the third in a series of articles for this website.
The features of the example appwere explained together with how the URLs can be built up in code from the various options selected.

It was also used to explain several of the procedures involved.



8.   Feedback                                                                                                                                   Return To Top

      Please use the contact form below to let me know whether you found this article useful or if you have any questions.

      Please also consider making a donation towards the costs of maintaining this website. Thank you

      You may also be interested in my commercial app UK Postal Address Finder which includes all the above features as a small part of a much larger set of features.



Colin Riddington           Mendip Data Systems                 Last Updated 7 Dec 2022



Return to Access Articles Page 3 of 3 1 2 3 Return To Top