Geocoding

geopandas supports geocoding (i.e., converting place names to location on Earth) through geopy, an optional dependency of geopandas. The following example shows how to get the locations of boroughs in New York City, and plots those locations along with the detailed borough boundary file included within geopandas.

In [1]: boros = geopandas.read_file(geopandas.datasets.get_path("nybb"))

In [2]: boros.BoroName
Out[2]: 
0    Staten Island
1           Queens
2         Brooklyn
3        Manhattan
4            Bronx
Name: BoroName, dtype: object

In [3]: boro_locations = geopandas.tools.geocode(boros.BoroName)
---------------------------------------------------------------------------
timeout                                   Traceback (most recent call last)
~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/site-packages/geopy/geocoders/base.py in _call_geocoder(self, url, timeout, raw, requester, deserializer, **kwargs)
    354         try:
--> 355             page = requester(req, timeout=timeout, **kwargs)
    356         except Exception as error:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/urllib/request.py in open(self, fullurl, data, timeout)
    524 
--> 525         response = self._open(req, data)
    526 

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/urllib/request.py in _open(self, req, data)
    542         result = self._call_chain(self.handle_open, protocol, protocol +
--> 543                                   '_open', req)
    544         if result:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    502             func = getattr(handler, meth_name)
--> 503             result = func(*args)
    504             if result is not None:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/urllib/request.py in https_open(self, req)
   1392             return self.do_open(http.client.HTTPSConnection, req,
-> 1393                 context=self._context, check_hostname=self._check_hostname)
   1394 

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1352                 raise URLError(err)
-> 1353             r = h.getresponse()
   1354         except:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/http/client.py in getresponse(self)
   1353             try:
-> 1354                 response.begin()
   1355             except ConnectionError:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/http/client.py in begin(self)
    305         while True:
--> 306             version, status, reason = self._read_status()
    307             if status != CONTINUE:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/http/client.py in _read_status(self)
    266     def _read_status(self):
--> 267         line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
    268         if len(line) > _MAXLINE:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/socket.py in readinto(self, b)
    588             try:
--> 589                 return self._sock.recv_into(b)
    590             except timeout:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/ssl.py in recv_into(self, buffer, nbytes, flags)
   1070                   self.__class__)
-> 1071             return self.read(nbytes, buffer)
   1072         else:

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/ssl.py in read(self, len, buffer)
    928             if buffer is not None:
--> 929                 return self._sslobj.read(len, buffer)
    930             else:

timeout: The read operation timed out

During handling of the above exception, another exception occurred:

GeocoderTimedOut                          Traceback (most recent call last)
<ipython-input-3-2354aa2d31fd> in <module>
----> 1 boro_locations = geopandas.tools.geocode(boros.BoroName)

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/site-packages/geopandas/tools/geocoding.py in geocode(strings, provider, **kwargs)
     71         throttle_time = _get_throttle_time(provider)
     72 
---> 73     return _query(strings, True, provider, throttle_time, **kwargs)
     74 
     75 

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/site-packages/geopandas/tools/geocoding.py in _query(data, forward, provider, throttle_time, **kwargs)
    146         try:
    147             if forward:
--> 148                 results[i] = coder.geocode(s)
    149             else:
    150                 results[i] = coder.reverse((s.y, s.x), exactly_one=True)

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/site-packages/geopy/geocoders/geocodefarm.py in geocode(self, query, exactly_one, timeout)
    104         logger.debug("%s.geocode: %s", self.__class__.__name__, url)
    105         return self._parse_json(
--> 106             self._call_geocoder(url, timeout=timeout), exactly_one
    107         )
    108 

~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.8.2/lib/python3.7/site-packages/geopy/geocoders/base.py in _call_geocoder(self, url, timeout, raw, requester, deserializer, **kwargs)
    380                     raise GeocoderUnavailable('Service not available')
    381             elif isinstance(error, SocketTimeout):
--> 382                 raise GeocoderTimedOut('Service timed out')
    383             elif isinstance(error, SSLError):
    384                 if "timed out" in message:

GeocoderTimedOut: Service timed out

In [4]: boro_locations
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-796f7e9a655e> in <module>
----> 1 boro_locations

NameError: name 'boro_locations' is not defined

In [5]: import matplotlib.pyplot as plt

In [6]: fig, ax = plt.subplots()

In [7]: boros.to_crs("EPSG:4326").plot(ax=ax, color="white", edgecolor="black");

In [8]: boro_locations.plot(ax=ax, color="red");
_images/boro_centers_over_bounds.png

By default, the geocode function uses the GeoCode.Farm geocoding API with a rate limitation applied. But a different geocoding service can be specified with the provider keyword.

The argument to provider can either be a string referencing geocoding services, such as 'google', 'bing', 'yahoo', and 'openmapquest', or an instance of a Geocoder from geopy. See geopy.geocoders.SERVICE_TO_GEOCODER for the full list. For many providers, parameters such as API keys need to be passed as **kwargs in the geocode call.

For example, to use the OpenStreetMap Nominatim geocoder, you need to specify a user agent:

geopandas.tools.geocode(boros.BoroName, provider='nominatim', user_agent="my-application")

Attention

Please consult the Terms of Service for the chosen provider. The example above uses 'geocodefarm' (the default), for which free users are limited to 250 calls per day and 4 requests per second (geocodefarm ToS).