English

Problem: Geocoding services cannot find the correct candidates for an address if there is a spelling error at the beginning of the street name

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:

  1. In ArcMap, open the attribute table for your reference data or feature class.
  2. Right-click on the street name attribute, and click Summarize.
  3. Click OK to accept the defaults and create a summary table.
  4. 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.
  5. 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.
  6. 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

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

  8. Select all of the records in the table that you generated in Step 3.
  9. 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.

Related Information