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 use the Google geocoding API 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, provider="google")
---------------------------------------------------------------------------
gaierror                                  Traceback (most recent call last)
/usr/lib/python3.7/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1316                 h.request(req.get_method(), req.selector, req.data, headers,
-> 1317                           encode_chunked=req.has_header('Transfer-encoding'))
   1318             except OSError as err: # timeout error

/usr/lib/python3.7/http/client.py in request(self, method, url, body, headers, encode_chunked)
   1243         """Send a complete request to the server."""
-> 1244         self._send_request(method, url, body, headers, encode_chunked)
   1245 

/usr/lib/python3.7/http/client.py in _send_request(self, method, url, body, headers, encode_chunked)
   1289             body = _encode(body, 'body')
-> 1290         self.endheaders(body, encode_chunked=encode_chunked)
   1291 

/usr/lib/python3.7/http/client.py in endheaders(self, message_body, encode_chunked)
   1238             raise CannotSendHeader()
-> 1239         self._send_output(message_body, encode_chunked=encode_chunked)
   1240 

/usr/lib/python3.7/http/client.py in _send_output(self, message_body, encode_chunked)
   1025         del self._buffer[:]
-> 1026         self.send(msg)
   1027 

/usr/lib/python3.7/http/client.py in send(self, data)
    965             if self.auto_open:
--> 966                 self.connect()
    967             else:

/usr/lib/python3.7/http/client.py in connect(self)
   1398 
-> 1399             super().connect()
   1400 

/usr/lib/python3.7/http/client.py in connect(self)
    937         self.sock = self._create_connection(
--> 938             (self.host,self.port), self.timeout, self.source_address)
    939         self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

/usr/lib/python3.7/socket.py in create_connection(address, timeout, source_address)
    706     err = None
--> 707     for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    708         af, socktype, proto, canonname, sa = res

/usr/lib/python3.7/socket.py in getaddrinfo(host, port, family, type, proto, flags)
    747     addrlist = []
--> 748     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    749         af, socktype, proto, canonname, sa = res

gaierror: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
/usr/lib/python3/dist-packages/geopy/geocoders/base.py in _call_geocoder(self, url, timeout, raw, requester, deserializer, **kwargs)
    343         try:
--> 344             page = requester(req, timeout=timeout, **kwargs)
    345         except Exception as error:

/usr/lib/python3.7/urllib/request.py in open(self, fullurl, data, timeout)
    524 
--> 525         response = self._open(req, data)
    526 

/usr/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:

/usr/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:

/usr/lib/python3.7/urllib/request.py in https_open(self, req)
   1359             return self.do_open(http.client.HTTPSConnection, req,
-> 1360                 context=self._context, check_hostname=self._check_hostname)
   1361 

/usr/lib/python3.7/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1318             except OSError as err: # timeout error
-> 1319                 raise URLError(err)
   1320             r = h.getresponse()

URLError: <urlopen error [Errno -3] Temporary failure in name resolution>

During handling of the above exception, another exception occurred:

GeocoderServiceError                      Traceback (most recent call last)
<ipython-input-3-dd5cb0f23cae> in <module>()
----> 1 boro_locations = geopandas.tools.geocode(boros.BoroName, provider="google")

/build/python-geopandas-0.4.0/geopandas/tools/geocoding.py in geocode(strings, provider, **kwargs)
     60 
     61     """
---> 62     return _query(strings, True, provider, **kwargs)
     63 
     64 

/build/python-geopandas-0.4.0/geopandas/tools/geocoding.py in _query(data, forward, provider, **kwargs)
    124         try:
    125             if forward:
--> 126                 results[i] = coder.geocode(s)
    127             else:
    128                 results[i] = coder.reverse((s.y, s.x), exactly_one=True)

/usr/lib/python3/dist-packages/geopy/geocoders/googlev3.py in geocode(self, query, exactly_one, timeout, bounds, region, components, language, sensor)
    251         logger.debug("%s.geocode: %s", self.__class__.__name__, url)
    252         return self._parse_json(
--> 253             self._call_geocoder(url, timeout=timeout), exactly_one
    254         )
    255 

/usr/lib/python3/dist-packages/geopy/geocoders/base.py in _call_geocoder(self, url, timeout, raw, requester, deserializer, **kwargs)
    373                 if "timed out" in message:
    374                     raise GeocoderTimedOut('Service timed out')
--> 375             raise GeocoderServiceError(message)
    376 
    377         if hasattr(page, 'getcode'):

GeocoderServiceError: [Errno -3] Temporary failure in name resolution

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({"init": "epsg:4326"}).plot(ax=ax, color="white", edgecolor="black");

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

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.

Please consult the Terms of Service for the chosen provider.