How to find the address closest to a point using reverse geocoding


Summary While geocoding is used to find the point that corresponds to an address, reverse geocoding takes a point and finds the closest address.

In this topic


Finding the address closest to a point using reverse geocoding

When given a location on a map, if you want to find the address closest to that point, use reverse geocoding. The IReverseGeocoding and IReverseGeocodingProperties interfaces provide access to members for finding the address closest to a point.
  1. To define the maximum search tolerance in the units specified by the SearchDistanceUnits property, use the SearchDistance property when looking for an address represented by a point.

    The ReverseGeocode method returns a PropertySet that represents the address closest to the point passed as the location parameter.
The point object passed to the location parameter must be projected into the spatial reference used by the locator before it is passed to the ReverseGeocode parameter.
  1. Use the bReturnIntersection parameter to indicate whether the ReverseGeocode method should return an intersection address. The property names contained in the PropertySet correspond to the Field object names in the Fields collection returned by the AddressFields property on IAddressInputs on the locator. See the following code example:
[C#]
public void ReverseGeocode()
{
    // Open a workspace from a file geodatabase.
    System.Object obj = Activator.CreateInstance(Type.GetTypeFromProgID(
        "esriDataSourcesGDB.FileGDBWorkspaceFactory"));
    IWorkspaceFactory2 workspaceFactory = obj as IWorkspaceFactory2;
    IWorkspace workspace = workspaceFactory.OpenFromFile(@"C:\UnitedStates.gdb", 0);

    // Get a locator from the locator workspace.
    obj = Activator.CreateInstance(Type.GetTypeFromProgID(
        "esriLocation.LocatorManager"));
    ILocatorManager2 locatorManager = obj as ILocatorManager2;
    ILocatorWorkspace locatorWorkspace = locatorManager.GetLocatorWorkspace
        (workspace);
    IReverseGeocoding reverseGeocoding = (IReverseGeocoding)
        locatorWorkspace.GetLocator("USLocator");

    // Create a Point at which to find the address.
    IAddressGeocoding addressGeocoding = (IAddressGeocoding)reverseGeocoding;
    IFields matchFields = addressGeocoding.MatchFields;
    IField shapeField = matchFields.get_Field(matchFields.FindField("Shape"));
    IPoint point = new PointClass();
    point.SpatialReference = shapeField.GeometryDef.SpatialReference;
    point.X =  - 117.2;
    point.Y = 34.06;

    // Set the search tolerance for reverse geocoding.
    IReverseGeocodingProperties reverseGeocodingProperties = 
        (IReverseGeocodingProperties)reverseGeocoding;
    reverseGeocodingProperties.SearchDistance = 100;
    reverseGeocodingProperties.SearchDistanceUnits = esriUnits.esriFeet;

    // Find the address nearest the Point.
    IPropertySet addressProperties = reverseGeocoding.ReverseGeocode(point, false);

    // Print the address properties.
    IAddressInputs addressInputs = (IAddressInputs)reverseGeocoding;
    IFields addressFields = addressInputs.AddressFields;
    for (int i = 0; i < addressFields.FieldCount; i++)
    {
        IField addressField = addressFields.get_Field(i);
        Console.WriteLine(addressField.AliasName + ": " +
            addressProperties.GetProperty(addressField.Name));
    }
}
[VB.NET]
Public Sub ReverseGeocode()
    ' Open a workspace from a file geodatabase.
    Dim obj As System.Object = Activator.CreateInstance(Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"))
    Dim workspaceFactory As IWorkspaceFactory2 = obj
    Dim workspace As IWorkspace = workspaceFactory.OpenFromFile("C:\UnitedStates.gdb", 0)
    
    ' Get a locator from the locator workspace.
    obj = Activator.CreateInstance(Type.GetTypeFromProgID("esriLocation.LocatorManager"))
    Dim locatorManager As ILocatorManager2 = obj
    Dim locatorWorkspace As ILocatorWorkspace = locatorManager.GetLocatorWorkspace(workspace)
    Dim locator As ILocator = locatorWorkspace.GetLocator("USLocator")
    Dim reverseGeocoding As IReverseGeocoding = locator
    
    ' Create a Point at which to find the address.
    Dim addressGeocoding As IAddressGeocoding = reverseGeocoding
    Dim matchFields As IFields = addressGeocoding.MatchFields
    Dim shapeField As IField = matchFields.Field(matchFields.FindField("Shape"))
    Dim point As IPoint = New Point
    point.SpatialReference = shapeField.GeometryDef.SpatialReference
    point.X = -117.2
    point.Y = 34.06
    
    ' Set the search tolerance for reverse geocoding.
    Dim reverseGeocodingProperties As IReverseGeocodingProperties = reverseGeocoding
    reverseGeocodingProperties.SearchDistance = 100
    reverseGeocodingProperties.SearchDistanceUnits = esriUnits.esriMeters
    
    ' Find the address nearest the Point.
    Dim addressProperties As IPropertySet = reverseGeocoding.ReverseGeocode(point, False)
    
    ' Print the address properties.
    Dim addressInputs As IAddressInputs = locator
    Dim addressFields As IFields = addressInputs.AddressFields()
    For i As Integer = 0 To addressFields.FieldCount - 1
        Dim addressField As IField = addressFields.Field(i)
        Console.WriteLine(addressField.AliasName + ": " + addressProperties.GetProperty(addressField.Name))
    Next
End Sub

Reverse geocode using IGeocodeServer

When given a location on a map, if you want to find the address closest to that point, use reverse geocoding. The ReverseGeocode and GetLocatorProperties methods for IGeocodeServer can be used to find the address closest to a point.
  1. To define the maximum search tolerance in the units specified by the "ReverseDistanceUnits" property, use the "ReverseDistance" property when looking for an address represented by a point.

    The ReverseGeocode method returns a PropertySet that represents the address closest to the point passed as the location parameter.
[VB.NET]
Sub ReverseGeocodeClientAgainstServer()
    
    ' Open a GISServerConnection.
    Dim gisServerConnection As IGISServerConnection = New GISServerConnectionClass
    gisServerConnection.Connect("mendota")
    
    ' Get a GeocodeServer from the GISServerConnection.
    Dim serverObjectManager As IServerObjectManager = gisServerConnection.ServerObjectManager
    Dim serverContext As IServerContext = serverObjectManager.CreateServerContext("USA Streets", "GeocodeServer")
    Dim serverObject_GeocodeServer As IServerObject = serverContext.ServerObject
    Dim geocodeServer As IGeocodeServer = CType(serverObject_GeocodeServer, IGeocodeServer)
    
    ' Create a point for which to find the address
    Dim resultFields As IFields = geocodeServer.GetResultFields(Nothing)
    Dim shapeField As IField = resultFields.Field(resultFields.FindField("Shape"))
    Dim point As IPoint = New Point
    point.X = -117.2
    point.Y = 34.06
    
    ' Set the reverse geocoding properties
    Dim locatorProperties = geocodeServer.GetLocatorProperties()
    locatorProperties.SetProperty("ReverseDistance", "100")
    locatorProperties.SetProperty("ReverseDistanceUnits", "Meters")
    Dim address As IPropertySet = geocodeServer.ReverseGeocode(point, False, locatorProperties)
    
    ' Print out the Address Properties
    Dim Key, Value As Object
    address.GetAllProperties(Key, Value)
    Dim keyArray() As Object = Key
    Dim valueArray() As Object = Value
    Dim arrayLength As Integer = keyArray.Length
    Dim addressPoint As IPoint
    For i As Integer = 0 To arrayLength - 1
        If (keyArray(i).ToString() = "Shape") Then
            addressPoint = valueArray(i)
            If (Not addressPoint.IsEmpty()) Then
                Console.WriteLine(keyArray(i).ToString() + " = " + addressPoint.X.ToString() + ", " + addressPoint.Y.ToString())
            End If
        Else
            Console.WriteLine(keyArray(i).ToString() + " = " + valueArray(i).ToString())
        End If
    Next
End Sub
[C#]
public void ReverseGeocodeClientAgainstServer()
{

    // Open a GISServerConnection.
    IGISServerConnection gisServerConnection = new GISServerConnectionClass();
    gisServerConnection.Connect("mendota");

    // Get a GeocodeServer from the GISServerConnection.
    IServerObjectManager serverObjectManager =
        gisServerConnection.ServerObjectManager;
    IServerContext serverContext = serverObjectManager.CreateServerContext(
        "USA Streets", "GeocodeServer");
    IServerObject serverObject_GeocodeServer = serverContext.ServerObject;
    IGeocodeServer geocodeServer = (IGeocodeServer)serverObject_GeocodeServer;

    // Create a point for which to find the address
    IFields resultFields = geocodeServer.GetResultFields(null);
    IField shapeField = resultFields.get_Field(resultFields.FindField("Shape"));
    IPoint point = new PointClass();
    point.SpatialReference = shapeField.GeometryDef.SpatialReference;
    point.X =  - 117.2;
    point.Y = 34.06;

    // Set the reverse geocoding properties
    IPropertySet locatorProperties = geocodeServer.GetLocatorProperties();
    locatorProperties.SetProperty("ReverseDistance", "100");
    locatorProperties.SetProperty("ReverseDistanceUnits", "Meters");

    IPropertySet address = geocodeServer.ReverseGeocode(point, false,
        locatorProperties);

    // Print out the Standardized Address
    object key, value;
    address.GetAllProperties(out key, out value);

    object[] keyArray = key as object[];
    object[] valueArray = value as object[];

    for (int i = 0; i < keyArray.Length; i++)
    {
        if (keyArray[i].ToString() == "Shape")
        {
            IPoint addressPoint = valueArray[i] as IPoint;
            Console.WriteLine(keyArray[i] + " = " + addressPoint.X + ", " +
                addressPoint.Y);
        }
        else
            Console.WriteLine(keyArray[i] + " = " + valueArray[i]);
    }
}


See Also:

Location library overview
Sample: Find the closest intersection from a point
How to reverse geocode point features in a feature class




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
Engine Developer Kit Engine Runtime
ArcView ArcView
ArcEditor ArcEditor
ArcInfo ArcInfo