Description
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.
Cause
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
End Sub
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.