|
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 |