ArcGIS Developers
Dashboard

ArcGIS API for Python

Part 5 - Reverse Geocoding

Introduction

The reverse_geocode() function in the arcgis.geocoding module determines the address at a particular x/y location. You can pass the coordinates of a point location to the geocoder and get returned the address that is closest (or nearest) to the location.

In [1]:
from arcgis.geocoding import reverse_geocode

help(reverse_geocode)
Help on function reverse_geocode in module arcgis.geocoding._functions:

reverse_geocode(location, distance=None, out_sr=None, lang_code=None, return_intersection=False, for_storage=False, geocoder=None, feature_types=None, roof_top='street')
    The reverse_geocode operation determines the address at a particular
    x/y location. You pass the coordinates of a point location to the
    geocoding service, and the service returns the address that is
    closest to the location.
    
    =================== ====================================================
    **Argument**        **Description**
    ------------------- ----------------------------------------------------
    location            required list/Point Geometry
    ------------------- ----------------------------------------------------
    distance            optional float, radial distance in meteres to
                        search for an address.  The default is 100 meters.
    ------------------- ----------------------------------------------------
    out_sr              optional integer, spatial reference of the x/y
                        coordinate returned.
    ------------------- ----------------------------------------------------
    lang_code           optional string. Sets the language in which geocode
                        results are returned. This is useful for ensuring
                        that results are returned in the expected language.
                        If the lang_code parameter isn't included in a
                        request, or if it is included but there are no
                        matching features with the input language code, the
                        resultant match is returned in the language code of
                        the primary matched components from the input search
                        string.
    ------------------- ----------------------------------------------------
    return_intersection optional Boolean, which specifies whether the
                        service should return the nearest street
                        intersection or the nearest address to the input
                        location
    ------------------- ----------------------------------------------------
    for_storage         optional boolean, specifies whether the results of
                        the operation will be persisted
    ------------------- ----------------------------------------------------
    geocoder            optional geocoder, the geocoder to be used. If not
                        specified, the active GIS's first geocoder is used.
    ------------------- ----------------------------------------------------
    feature_types       Optional String. Limits the possible match types
                        performed by the `reverse_geocode` method. If a
                        single value is included, the search tolerance for
                        the input feature type is 500 meters. If multiple
                        values (separated by a comma, with no spaces) are
                        included, the default search distances specified in
                        the feature type hierarchy table are applied.
    
                        Values: StreetInt, DistanceMarker, StreetAddress,
                                StreetName, POI, PointAddress, Postal, and
                                Locality
    ------------------- ----------------------------------------------------
    location_type       Optional string. Specifies whether the rooftop point
                        or street entrance is used as the output geometry of
                        point address matches. By default, street is used,
                        which is useful in routing scenarios, as the rooftop
                        location of some addresses may be offset from a
                        street by a large distance. However, for map display
                        purposes, you may want to use rooftop instead,
                        especially when large buildings or landmarks are
                        geocoded. The location_type parameter only affects
                        the location object in the JSON response and does
                        not change the x,y or DisplayX/DisplayY attribute
                        values.
    
                        Values: street, rooftop
    =================== ====================================================
    
    :returns:
       dictionary

The required location parameter

As shown in the help output above, the only required input parameter of reverse_geocode() is the location parameter, which is the point from which to search for the closest address. The point can be represented as a simple list of coordinates ([x, y] or [longitude, latitude]), a dict object (with or without spatial reference) or JSON point object, or a Point Geometry object.

The spatial reference of the list of coordinates is always WGS84 (in decimal degress), the same coordinate system as the World Geocoding Service.

Use JSON formatting to specify any other coordinate system for the input location. Specifically, set the spatial reference using its well-known ID (WKID) value. For a list of valid WKID values, see Projected Coordinate Systems and Geographic Coordinate Systems.

Example using simple syntax and the default WGS84 spatial reference:

location=[103.8767227,1.3330736]

Example using JSON and the default WGS84 spatial reference:

location={"x": 103.876722, "y": 1.3330736}

Example using JSON and specifying a spatial reference (WGS84 Web Mercator Auxiliary Sphere):

location= { "x": 11563503, "y": 148410, "spatialReference": { "wkid": 3857 } }

The simple reverse geocode examples

Next, we will look at different kinds of input for the location parameter - (1) list, (2) dict, (3) dict with sr, and (4) Point object. Note that, when composing a list containing x/y coordinates, the order is X,Y and not Y,X as in lat, long.

In [2]:
from arcgis.gis import GIS
from arcgis.geocoding import reverse_geocode

gis = GIS(profile="your_online_profile")

Example 1 - location input as list

In [ ]:
results = reverse_geocode([2.2945, 48.8583])
In [6]:
type(results)
Out[6]:
dict
In [5]:
results
Out[5]:
{'address': {'Match_addr': 'Salle Gustave Eiffel',
  'LongLabel': 'Salle Gustave Eiffel, Avenue Gustave Eiffel, 75007, 7e Arrondissement, Paris, Île-de-France, FRA',
  'ShortLabel': 'Salle Gustave Eiffel',
  'Addr_type': 'POI',
  'Type': 'Convention Center',
  'PlaceName': 'Salle Gustave Eiffel',
  'AddNum': '',
  'Address': 'Avenue Gustave Eiffel',
  'Block': '',
  'Sector': '',
  'Neighborhood': 'Gros Caillou',
  'District': '7e Arrondissement',
  'City': 'Paris',
  'MetroArea': '',
  'Subregion': 'Paris',
  'Region': 'Île-de-France',
  'Territory': '',
  'Postal': '75007',
  'PostalExt': '',
  'CountryCode': 'FRA'},
 'location': {'x': 2.2951599583073303,
  'y': 48.85784000836726,
  'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}}

Example 2 - location input as dict

In [11]:
results = reverse_geocode(location={"x": 103.876722, "y": 1.3330736})
results
Out[11]:
{'address': {'Match_addr': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore',
  'LongLabel': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore, SGP',
  'ShortLabel': 'Sennett Estate, 40 Lichi Avenue',
  'Addr_type': 'PointAddress',
  'Type': '',
  'PlaceName': '',
  'AddNum': '40',
  'Address': 'Sennett Estate, 40 Lichi Avenue',
  'Block': '',
  'Sector': '',
  'Neighborhood': '',
  'District': '',
  'City': 'Singapore',
  'MetroArea': '',
  'Subregion': '',
  'Region': 'Singapore',
  'Territory': '',
  'Postal': '348814',
  'PostalExt': '',
  'CountryCode': 'SGP'},
 'location': {'x': 103.87671885261159,
  'y': 1.333058719212687,
  'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}}

Example 3 - location input as dict with sr

In [12]:
results = reverse_geocode(location= { "x": 11563503, "y": 148410, "spatialReference": { "wkid": 3857 } })
results
Out[12]:
{'address': {'Match_addr': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore',
  'LongLabel': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore, SGP',
  'ShortLabel': 'Sennett Estate, 40 Lichi Avenue',
  'Addr_type': 'PointAddress',
  'Type': '',
  'PlaceName': '',
  'AddNum': '40',
  'Address': 'Sennett Estate, 40 Lichi Avenue',
  'Block': '',
  'Sector': '',
  'Neighborhood': '',
  'District': '',
  'City': 'Singapore',
  'MetroArea': '',
  'Subregion': '',
  'Region': 'Singapore',
  'Territory': '',
  'Postal': '348814',
  'PostalExt': '',
  'CountryCode': 'SGP'},
 'location': {'x': 103.87671885261159,
  'y': 1.333058719212687,
  'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}}

Example 4 - location input as Point Geometry object

In [7]:
from arcgis.geometry import Geometry

pt = Geometry({
    "x": 11563503,
    "y": 148410,
    "spatialReference": {
        "wkid": 3857
    }
})
In [8]:
results = reverse_geocode(pt)
type(results)
Out[8]:
dict
In [9]:
results
Out[9]:
{'address': {'Match_addr': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore',
  'LongLabel': 'Sennett Estate, 40 Lichi Avenue, 348814, Singapore, SGP',
  'ShortLabel': 'Sennett Estate, 40 Lichi Avenue',
  'Addr_type': 'PointAddress',
  'Type': '',
  'PlaceName': '',
  'AddNum': '40',
  'Address': 'Sennett Estate, 40 Lichi Avenue',
  'Block': '',
  'Sector': '',
  'Neighborhood': '',
  'District': '',
  'City': 'Singapore',
  'MetroArea': '',
  'Subregion': '',
  'Region': 'Singapore',
  'Territory': '',
  'Postal': '348814',
  'PostalExt': '',
  'CountryCode': 'SGP'},
 'location': {'x': 103.87671885261159,
  'y': 1.333058719212687,
  'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}}

Reverse geocode a location clicked on the map

There are situations when the input location is not known beforehand, and instead relies on the user to click a location. The example below illustrates how to define a handler function (e.g. find_addr()) and an event listener (per user clicking on the map e.g. on_click()) to handle these instances.

In [17]:
map1 = gis.map('Redlands, CA', 14)
map1

The corresponding addresses for the four clicked points shown above are listed here:

207 Redlands Mall, Redlands, California, 92373
125 W Vine St, Redlands, California, 92373
Redlands Fire Department Station 261
137 E Vine St, Redlands, California, 92373
In [16]:
def find_addr(m, g):
    try:
        geocoded = reverse_geocode(g)
        m.draw(g)
        print(geocoded['address']['Match_addr'])
    except:
        print("Couldn't match address. Try another place...")

map1.on_click(find_addr)

Get result as intersection instead of address (return_intersection param)

Facts about the return_intersection parameter:

  • A Boolean which specifies whether the service should return the nearest street intersection or the nearest address to the input location.
  • If True, then the closest intersection to the input location is returned;
  • if False, then the closest address to the input location is returned.
  • The default value is False.
In [30]:
# Let's take a look at the intersection of W. Vine St & S 4th St in the city of Redlands, CA
Out[30]:
In [25]:
from arcgis.geocoding import geocode
intersect_loc = geocode("S 4th St & W Vine, Redlands, CA")[0]['location']
print(intersect_loc)
{'x': -117.18361987601203, 'y': 34.0546600260095}

When the return_intersection parameter is not specified, or set to False, then the closest address to the input location is returned. We can see below that the returned address is a StreetAddress, instead of intersection, and that the matched addresses are of Street number 130 to 134 on the S 4th St.

In [26]:
reverse_geocode(intersect_loc)
Out[26]:
{'address': {'Match_addr': '130-134 S 4th St, Redlands, California, 92373',
  'LongLabel': '130-134 S 4th St, Redlands, CA, 92373, USA',
  'ShortLabel': '130-134 S 4th St',
  'Addr_type': 'StreetAddress',
  'Type': '',
  'PlaceName': '',
  'AddNum': '130',
  'Address': '130 S 4th St',
  'Block': '',
  'Sector': '',
  'Neighborhood': 'South Redlands',
  'District': '',
  'City': 'Redlands',
  'MetroArea': 'Inland Empire',
  'Subregion': 'San Bernardino County',
  'Region': 'California',
  'Territory': '',
  'Postal': '92373',
  'PostalExt': '',
  'CountryCode': 'USA'},
 'location': {'x': -117.18367019351942,
  'y': 34.054620721017486,
  'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}}