Skip to content

Geographic Decoder


get_geoinfo(address, city=None, state=None)

Given a street address, city, and state, this function will call the ArcGIS API and geocode the location - returning the full address and the longitude/latitude coordinate pair for the mapped location. Function will automatically convert all parameters to strings.

Parameters:

Name Type Description Default
address object

street address for the location to geocode

required
city object

the U.S. city the location is located in

None
state object

the U.S. state the location is located in

None

Returns:

Type Description
list[str, tuple]

list containing [0] the official address obtained from the ArcGIS API, and [1] the longitute/latitude coordinate pair

Examples:

To geocode a single street address:

>>> from msa_mapper import get_geoinfo
>>> get_geoinfo('801 Grand Ave', 'Des Moines')
Out[1]: ['801 Grand Ave, Des Moines, IA 50309',
...      (-93.6285390023275, 41.58744200206709)]

To geocode multiple addresses stored in a pandas DataFrame (addresses_pdf) with columns for each parameter (Address, City, State), we recommend installing and importing pandarallel to parallelize the apply function:

>>> import multiprocessing
>>> from pandarallel import pandarallel
>>> num_cores = multiprocessing.cpu_count()
>>> pandarallel.initialize(progress_bar=True,
...                        nb_workers=(num_cores - 1))
>>> def func_name(x):
...     from msa_mapper import get_geoinfo
...     return get_geoinfo(x.Address, x.City, x.State)
>>> res = (
...       addresses_pdf
...       .parallel_apply(func_name, axis=1)
... )
>>> addresses = res.str[0].tolist()
>>> coords = res.str[1].tolist()
Source code in msa_mapper\geocoder.py
def get_geoinfo(address, city=None, state=None):
    """
    Given a street address, city, and state, this function will
    call the ArcGIS API and geocode the location - returning the full
    address and the longitude/latitude coordinate pair for the mapped location.
    Function will automatically convert all parameters to strings.

    Args:
        address (object): street address for the location to geocode
        city (object): the U.S. city the location is located in
        state (object): the U.S. state the location is located in

    Returns:
        list[str, tuple]: list containing [0] the official address obtained
            from the ArcGIS API, and [1] the longitute/latitude coordinate pair

    Example:
        To geocode a single street address:

        >>> from msa_mapper import get_geoinfo
        >>> get_geoinfo('801 Grand Ave', 'Des Moines')
        Out[1]: ['801 Grand Ave, Des Moines, IA 50309',
        ...      (-93.6285390023275, 41.58744200206709)]

        To geocode multiple addresses stored in a pandas DataFrame
        (`addresses_pdf`) with columns for each parameter
        (`Address`, `City`, `State`), we recommend installing and importing
        `pandarallel` to parallelize the apply function:

        >>> import multiprocessing
        >>> from pandarallel import pandarallel

        >>> num_cores = multiprocessing.cpu_count()
        >>> pandarallel.initialize(progress_bar=True,
        ...                        nb_workers=(num_cores - 1))

        >>> def func_name(x):
        ...     from msa_mapper import get_geoinfo
        ...     return get_geoinfo(x.Address, x.City, x.State)

        >>> res = (
        ...       addresses_pdf
        ...       .parallel_apply(func_name, axis=1)
        ... )
        >>> addresses = res.str[0].tolist()
        >>> coords = res.str[1].tolist()
    """
    if address:
        address = (
            str(address)
            .split('-')[-1]
            .split('&')[-1]
            .split(';')[-1]
            .strip()
            .encode('ascii', errors='ignore')
            .decode()
        )

    city_filtered = str(city).lower().strip()
    if city and city_filtered not in ('vr', 'various'):
        city = city_filtered.encode('ascii', errors='ignore').decode()
    else:
        city = None

    state_filtered = str(state).upper().strip()
    if state and state_filtered in state_mapping().keys():
        state = (
            state_filtered
            .encode('ascii', errors='ignore').decode()
        )
    else:
        state = None

    search = ', '.join(id for id in [address, city, state] if id)
    response = geocoder.arcgis(search, timeout=30)

    if response.ok:
        return _obtain_attributes(response)
    else:
        time.sleep(3)
        response = geocoder.arcgis(search, timeout=30)
        if response.ok:
            return _obtain_attributes(response)
        else:
            return None