Home arrow Site Info arrow Latest Portal Content arrow VBA: Use a Web Service in ArcMap (To Geocode)
VBA: Use a Web Service in ArcMap (To Geocode) PDF Print E-mail

Written by Bert Granberg,

The script below shows an example of how to use a web service from within ArcMap. Admittedly, web services are much more easy to work with from a .NET language such as VB.NET or C#.NET but it can be done from within ArcMap's VBA environment.

The code below shows an example of how to use an existing web service hosted on AGRC's mapserv.utah.gov site to geocode an address. Read the commented lines for prerequisite including obtaining and using the  Microsoft Office XP Web Services Toolkit 2.0 and registering a username for mapserv.utah.gov.

Why use a web service to geocode and address? In this case the GeoLocator web service has been customized to search all zip codes listed for the input city parameter so it's possible to find an address without the correct zip code. Parsing the web service response is a lot easier than writing your own custome code to perform the same task.

Public Sub testWS()

    'AGRC-BG 12/12/07 

    'BEFORE USING THIS SCRIPT IN ARCMAP, YOU MUST:
    
    '1) Download & Install Microsoft Office XP Web Services Toolkit 2.0 from
    '   http://www.microsoft.com/downloads/details.aspx?FamilyId=4922060F-002A-4F5B-AF74-978F2CD6C798&displaylang=en
    '
    '2) From within the VBA Interface's Tools>>References menu
    '   Enable the reference: Microsoft Soap Type Library 3.0
    '   Enable the referebce: Microsoft XML 6.0
    '
    '3) Register with mapserv.utah.gov to get a username (set variable below to your
    '   username) to test the GeoLocator web service,
    '   or, change the code to reference another webservice and its operations.   

    Dim mapServUserName As String
    mapServUserName = "yourMapServUserName"
    
    Dim WSDLAddress As String
    WSDLAddress = "http://mapserv.utah.gov/WSUTSGID_Geolocator/Default.asmx?wsdl"
    
    Dim i As Long
    Dim x As Long

    Dim objSClient As MSSOAPLib30.SoapClient30      ' Remove the 30 if using an earlier version of SOAP
    
    'A n object of type IXMLDOMNodeList is declared to parse the Web service's returned data.
    Dim objResults As MSXML2.IXMLDOMNodeList
    Dim objResultsNode As MSXML2.IXMLDOMNode

    ' Point the SOAP API to the web service that we want to call...
    Set objSClient = New SoapClient30
    Call objSClient.MSSoapInit(par_WSDLFile:=WSDLAddress)

    ' Call a specific web service operation
    '   The example web service operation is called GeocodeAddress and
    '   takes 3 arguments: [username], [street address], [zip code or city]
    Set objResults = objSClient.GeocodeAddress(mapServUserName, "1637 S Main", "84115")
    
    Set objResultsNode = objResults.nextNode
    
    'The example returns MatchAddress, GeoLocator, MatchScore, UTMX, UTMY, Longitude, Latitude
    Do Until objResultsNode Is Nothing
        i = i + 1
        Debug.Print "Result #" & i
        For x = 0 To objResults.Length - 1
            Debug.Print objResults(x).nodeTypedValue
        Next x
        Debug.Print ""
        Set objResultsNode = objResults.nextNode
    Loop
   
    Set objSClient = Nothing
    Set objResults = Nothing
    Set objResultsNode = Nothing
    
End Sub

 

'Modified code example to use the geocode web service in bulk against a table....

Public Sub bulkTableGC()
    On Error GoTo Errorhandler
    'AGRC-BG 09/24/12/09
    
    'BEFORE USING THIS SCRIPT IN ARCMAP, YOU MUST:
    
    '1) Download & Install Microsoft Office XP Web Services Toolkit 2.0 from
    ' http://www.microsoft.com/downloads/details.aspx?FamilyId=4922060F-002A-4F5B-AF74-978F2CD6C798&displaylang=en
    '
    '2) From within the VBA Interface's Tools>>References menu
    ' Enable the reference: Microsoft Soap Type Library 3.0
    ' Enable the referebce: Microsoft XML 6.0
    '
    '3) Register with mapserv.utah.gov to get a username (set variable below to your
    ' username) to test the GeoLocator web service,
    ' or, change the code to reference another webservice and its operations.
    
    Dim mapServUserName As String
    mapServUserName = "YOURMAPSERVUSERNAMEHERE"
    
    Dim WSDLAddress As String
    WSDLAddress = "http://dagrc.utah.gov/WSUTSGID_Geolocator/Default.asmx?wsdl"
    
    Dim i As Integer
    Dim x As Integer
    Dim objSClient As MSSOAPLib30.SoapClient30 ' Remove the 30 if using an earlier version of SOAP
    
    'A n object of type IXMLDOMNodeList is declared to parse the Web service's returned data.
    Dim objResults As MSXML2.IXMLDOMNodeList
    Dim objResultsNode As MSXML2.IXMLDOMNode
    
    ' Point the SOAP API to the web service that we want to call...
    Set objSClient = New SoapClient30
    Call objSClient.MSSoapInit(par_WSDLFile:=WSDLAddress)
    
    ' Call a specific web service operation
    ' The example web service operation is called GeocodeAddress and
    ' takes 3 arguments: [username], [street address], [zip code or city]
 
    Dim pMxDoc As IMxDocument
    Dim pTC As ITableCollection
    Dim pCursor As ICursor
    Dim pRow As IRow
    Dim pTable As ITable
    Dim pDS As IDataset
    Dim proceed As Long
    Dim pQF As IQueryFilter
 
    Set pMxDoc = ThisDocument
    Set pTC = pMxDoc.FocusMap
    Set pTable = pTC.Table(0) 'SET THE TABLE NUMBER HERE
    Set pDS = pTable
    Set pQF = New QueryFilter
    'pQF.WhereClause = ""
    pQF.WhereClause = "COUNTY_CITY like 'CA%'"
    'pQF.WhereClause = "COUNTY_CITY like 'CA%' and GC_STATUS = 'U'"
    Debug.Print pDS.BrowseName
    proceed = MsgBox("Geocode Table Named: " & pDS.BrowseName, vbOKCancel)
 
    If proceed = vbCancel Then
        Exit Sub
    End If
 
    Set pCursor = pTable.Search(pQF, True)
    Set pRow = pCursor.NextRow
 
    Dim addressStr As String
    Dim zoneStr As String
    Dim currTime As Date
    Dim errorEncountered As Boolean
    Dim count As Long
   
    Do Until pRow Is Nothing
        count = count + 1
        errorEncountered = False
        currTime = Now
       
        addressStr = ""
       
        If Not IsNull(pRow.Value(pTable.FindField("HOUSE_NO"))) Then
            If pRow.Value(pTable.FindField("HOUSE_NO")) <> "" Then
                addressStr = pRow.Value(pTable.FindField("HOUSE_NO")) & " "
            End If
        End If
       
        If Not IsNull(pRow.Value(pTable.FindField("DIRECTION"))) Then
            If pRow.Value(pTable.FindField("DIRECTION")) <> "" Then
                addressStr = addressStr & pRow.Value(pTable.FindField("DIRECTION")) & " "
            End If
        End If
       
        If Not IsNull(pRow.Value(pTable.FindField("STREET_NAME"))) Then
            If pRow.Value(pTable.FindField("STREET_NAME")) <> "" Then
                addressStr = addressStr & pRow.Value(pTable.FindField("STREET_NAME")) & " "
            End If
        End If
       
        If Len(addressStr) > 2 Then
            If InStr(addressStr, " ") > 0 Then
                If Left(addressStr, 1) > 0 And Left(addressStr, 1) < 10 Then

                    zoneStr = pRow.Value(pTable.FindField("ZONE"))
            
                    Set objResults = objSClient.GeocodeAddress(mapServUserName, addressStr, zoneStr)
            
                    Set objResultsNode = objResults.nextNode
            
                    Do Until objResultsNode Is Nothing
           
                        i = i + 1
                        'Debug.Print "Result #" & i
           
                        For x = 0 To objResults.Length - 1
            
                            'Debug.Print objResults(x).nodeTypedValue
                            If x = 4 Then
                                pRow.Value(pTable.FindField("GCAdd")) = objResults(x).nodeTypedValue
                            ElseIf x = 0 Then
                                pRow.Value(pTable.FindField("GCLocator")) = Replace((objResults(x).nodeTypedValue), "TRANSPORTATION.", "")
                            ElseIf x = 1 Then
                                pRow.Value(pTable.FindField("GCScore")) = CLng(objResults(x).nodeTypedValue)
                            ElseIf x = 2 Then
                                pRow.Value(pTable.FindField("X")) = CDbl(objResults(x).nodeTypedValue)
                            ElseIf x = 3 Then
                                pRow.Value(pTable.FindField("Y")) = CDbl(objResults(x).nodeTypedValue)
                            End If
            
                        Next x
                       
                        If Not errorEncountered Then
                            pRow.Store
                            Debug.Print count; addressStr; zoneStr; DateDiff("s", currTime, Now)
                        Else
                            Debug.Print count; "ERROR "; addressStr; zoneStr; DateDiff("s", currTime, Now)
                            pRow.Value(pTable.FindField("GCAdd")) = Null
                            pRow.Value(pTable.FindField("GCLocator")) = Null
                            pRow.Value(pTable.FindField("GCScore")) = Null
                            pRow.Value(pTable.FindField("X")) = Null
                            pRow.Value(pTable.FindField("Y")) = Null
                       
                        End If
                       
                        Exit Do
                        'Set objResultsNode = objResults.nextNode
            
                    Loop
                End If
            End If
        End If
       
        Set pRow = pCursor.NextRow
        'If count = 300 Then
        '    Debug.Print "here"
        'End If
    Loop
 
    Set objSClient = Nothing
    Set objResults = Nothing
    Set objResultsNode = Nothing
   
    Exit Sub

Errorhandler:
    errorEncountered = True
    Debug.Print Err.Number; Err.Description
    If Err.Number = 5415 Then
        'timeout
        Set objSClient = New SoapClient30
        Call objSClient.MSSoapInit(par_WSDLFile:=WSDLAddress)
    End If
    Resume Next
   
End Sub

Users' Comments  
 

Display 2 of 2 comments

1. Wed, 12-12-2007 at 01:00 PM

Will AGRC be producing a list of web services that they think folks would like to see in ArcMap? Do you think AGRC will do some kind of webcast with a demo of this functionality?

2. Fri, 12-14-2007 at 02:05 PM

 
 
This [link] url might be of interest...

Display 2 of 2 comments

Add your comment

12, Dec. 2007
Last Updated ( 01, Oct. 2009 )
 
< Prev   Next >

AGRC Contacts | UGIC Contacts

feed image feed image

Utah GIS Portal © 2009 AGRC

Optimized for