Problem: Geocoding services cannot find the correct candidates for an address if there is a spelling error at the beginning of the street name
When geocoding addresses, geocoding services cannot find the correct candidates, or any candidates at all, for an address that has a spelling error at the beginning of the street name in the address.
The index that geocoding services use to find candidates for addresses is very sensitive to the first characters in the street name. This index uses something called the Soundex function. The Soundex value for a street name is a single character followed by three digits. See the document in the Related Information section for information on how Soundex values are calculated in ArcGIS.
When a geocoding service is created, a geocoding index is created that contains Soundex values for each of the street names in the reference data feature class or table. When searching for candidates for an address, the geocoding service generates a Soundex value for the street name and then searches the geocoding index for exact matches for this Soundex value. If, for example, the address is on New York Street (with a Soundex value of N620), the geocoding service will return all features in the reference data feature class or table from New York Street and Newark Street. If, however, the address contains a spelling error, for example, "New Yotk Street" (with a Soundex value of N320), these features will not be returned.
Solution or Workaround
The easiest way to avoid this problem is to ensure that there are no spelling errors in either your reference data or your address table. To perform these checks on your data, use the following procedure:
In ArcMap, open the attribute table for your reference data or feature class.
Right-click on the street name attribute, and click Summarize.
Click OK to accept the defaults and create a summary table.
Examine the contents of the summary table to determine if there are any spelling errors in the street names in the reference data table or feature class.
Edit the street names in the reference data or feature class or table. You will have to rebuild your geocoding indexes if you have already created the geocoding service. For more information on rebuilding geocoding indexes, see 'Managing geocoding indexes' in the ArcGIS Desktop Help.
Use the ADDRESSPARSE command in ArcInfo Workstation to standardize the addresses in your address table. For more information on the ADDRESSPARSE command, refer to 'ADDRESSPARSE' in the ARC/INFO Help.
Note: If your address table is not an INFO table, you will need to convert it to an INFO table before using the ADDRESSPARSE command. For more information on converting data to an INFO table, refer to 'dBASE to INFO' in the ArcToolbox Help.
Alternatively, you can use a VBA script to standardize the addresses in your address table. Paste the following code into the VBA editor in ArcCatalog, and write a procedure that calls the StandardizeAddressTable procedure. This code assumes that you already have a reference to the address table that you want to standardize and a reference to the geocoding service that you will use to standardize the addresses.
Public Sub StandardizeAddressTable(pTable As ITable, _ pLocator As ILocator) Const PROCEDURE_NAME = "StandardizeAddressTable" Dim i As Long Dim lngFieldIndex As Long Dim lngAddressFieldIndexes() As Long Dim lngStandardizeFieldIndexes() As Long Dim pAddressInputFields As IFields Dim pAddressInputs As IAddressInputs Dim pAddressPropertySet As IPropertySet Dim pAdvancedGeocoding As IAdvancedGeocoding Dim pCursor As ICursor Dim pRow As IRow Dim pStandardizeField As IField Dim pStandardizeFieldEdit As IFieldEdit Dim pStandardizeFields As IFields Dim pStandardizePropertySet As IPropertySet Dim strAddressFieldNames() As String Dim strNewFieldName As String Dim strStandardizeFieldNames() As String
' +++ Get the address Fields from the Table. If Not (TypeOf pLocator Is IAddressInputs) Then Exit Sub End If Set pAddressInputs = pLocator Set pAddressInputFields = pAddressInputs.AddressFields strAddressFieldNames = _ Split(AddressFields(pTable, pAddressInputs), ",") ' +++ Get the indexes of the address Fields in the Table. ReDim lngAddressFieldIndexes(0 To UBound(strAddressFieldNames)) For i = 0 To UBound(strAddressFieldNames) lngAddressFieldIndexes(i) = _ pTable.FindField(strAddressFieldNames(i)) Next i
' +++ Create the standardize Fields in the Table. If Not (TypeOf pLocator Is IAdvancedGeocoding) Then Exit Sub End If Set pAdvancedGeocoding = pLocator Set pStandardizeFields = pAdvancedGeocoding.StandardizeFields ReDim strStandardizeFieldNames(0 To pStandardizeFields.FieldCount) For i = 0 To pStandardizeFields.FieldCount - 1 Set pStandardizeField = pStandardizeFields.Field(i) lngFieldIndex = pTable.FindField(pStandardizeField.Name) ' +++ If the field exists in the table, ask the user if they want ' +++ to use this field. If (lngFieldIndex <> -1) Then Select Case MsgBox("The field " & pStandardizeField.Name & _ " already exists in the table. " & _ "Would you like to use this field?", vbYesNoCancel, _ PROCEDURE_NAME) Case vbYes ' +++ Do nothing; the Field already exists in the Table. Case vbNo ' +++ Prompt the user for a name for the new Field to use. Do strNewFieldName = _ InputBox("Please enter a name for the new field:", _ PROCEDURE_NAME, pStandardizeField.Name & CStr(1)) Loop Until (pTable.FindField(strNewFieldName) = -1) Set pStandardizeFieldEdit = pStandardizeField pStandardizeFieldEdit.Name = strNewFieldName pTable.AddField pStandardizeField Case vbCancel Exit Sub End Select Else pTable.AddField pStandardizeField End If strStandardizeFieldNames(i) = pStandardizeField.Name Next i
' +++ Standardize the addresses in the Table, and write the results ' +++ to the Fields. Set pCursor = pTable.Update(Nothing, False) ReDim lngStandardizeFieldIndexes _ (0 To pStandardizeFields.FieldCount - 1) For i = 0 To pStandardizeFields.FieldCount - 1 lngStandardizeFieldIndexes(i) = _ pCursor.FindField(strStandardizeFieldNames(i)) Next i Do Set pRow = pCursor.NextRow If (pRow Is Nothing) Then Exit Do ' +++ Construct an address for the Row. Set pAddressPropertySet = New PropertySet For i = 0 To UBound(strAddressFieldNames) pAddressPropertySet.SetProperty _ pAddressInputFields.Field(i).Name, _ pRow.Value(lngAddressFieldIndexes(i)) Next i ' +++ Standardize the address. Set pStandardizePropertySet = _ pAdvancedGeocoding.StandardizeAddress(pAddressPropertySet, False) For i = 0 To UBound(lngStandardizeFieldIndexes) pRow.Value(lngStandardizeFieldIndexes(i)) = _ pStandardizePropertySet.GetProperty _ (pStandardizeFields.Field(i).Name) Next i pCursor.UpdateRow pRow Loop
Public Function AddressFields(pTable As ITable, _ pAddressInputs As IAddressInputs) As String Const PROCEDURE_NAME = "AddressFields" Dim binFieldFound As Boolean Dim i As Long, j As Long, k As Long Dim pAddressFields As IFields Dim pTableFields As IFields Dim strAddressFieldNames() As String Dim strDefaultInputFieldNames() As String
' +++ Get the Fields from the Locator and from the Table. Set pAddressFields = pAddressInputs.AddressFields Set pTableFields = pTable.Fields
' +++ Redimension the array to hold the address Field names. ReDim strAddressFieldNames(0 To pAddressFields.FieldCount - 1)
' +++ Search the Table to find each of the address Fields. For i = 0 To pAddressFields.FieldCount - 1 binFieldFound = False ' +++ Get the default Fields names for this Field. strDefaultInputFieldNames = _ pAddressInputs.DefaultInputFieldNames _ (pAddressFields.Field(i).Name) For j = LBound(strDefaultInputFieldNames) _ To UBound(strDefaultInputFieldNames) For k = 0 To pTableFields.FieldCount - 1 ' +++ Compare the default name to this Field's name. If (StrComp(pTableFields.Field(k).Name, _ strDefaultInputFieldNames(j), vbTextCompare) = 0) Then strAddressFieldNames(i) = pTableFields.Field(k).Name binFieldFound = True Exit For End If Next k If binFieldFound Then Exit For Next j If Not (binFieldFound) Then ' +++ If the Field was required, then raise an error. If (pAddressFields.Field(i).Required) Then Err.Raise 1000, PROCEDURE_NAME, _ "Required address field missing." & "[" _ & pAddressFields.Field(i).Name & "]" End If End If Next i ' +++ Create a string from the array of Field names and return it. AddressFields = Join(strAddressFieldNames, ",") End Function
In ArcMap, load the standardized address table, and create a relate between this table and the results from Step 3 using the street name field in each table.
Note: Relates are case sensitive, so you may have to change the case of the street names in one of these tables before creating the relate. You can do this by calculating the values for a new field and using a Visual Basic script to convert the case for your street name field.
Select all of the records in the table that you generated in Step 3.
Click Options > Related Tables, then click the relate that you created with the standardized address table. The records that contain corresponding records in the summary table are now selected. The records that are not selected do not have features with corresponding street names in the reference data table or feature class. Some of these records may have spelling errors in the street name.