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.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1317                 h.request(req.get_method(), req.selector, req.data, headers,
-> 1318                           encode_chunked=req.has_header('Transfer-encoding'))
   1319             except OSError as err: # timeout error

/usr/lib/python3.6/http/client.py in request(self, method, url, body, headers, encode_chunked)
   1238         """Send a complete request to the server."""
-> 1239         self._send_request(method, url, body, headers, encode_chunked)
   1240 

/usr/lib/python3.6/http/client.py in _send_request(self, method, url, body, headers, encode_chunked)
   1284             body = _encode(body, 'body')
-> 1285         self.endheaders(body, encode_chunked=encode_chunked)
   1286 

/usr/lib/python3.6/http/client.py in endheaders(self, message_body, encode_chunked)
   1233             raise CannotSendHeader()
-> 1234         self._send_output(message_body, encode_chunked=encode_chunked)
   1235 

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

/usr/lib/python3.6/http/client.py in send(self, data)
    963             if self.auto_open:
--> 964                 self.connect()
    965             else:

/usr/lib/python3.6/http/client.py in connect(self)
   1391 
-> 1392             super().connect()
   1393 

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

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

/usr/lib/python3.6/socket.py in getaddrinfo(host, port, family, type, proto, flags)
    744     addrlist = []
--> 745     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    746         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)
    142         try:
--> 143             page = requester(req, timeout=(timeout or self.timeout), **kwargs)
    144         except Exception as error: # pylint: disable=W0703

/usr/lib/python3.6/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    222         opener = _opener
--> 223     return opener.open(url, data, timeout)
    224 

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

/usr/lib/python3.6/urllib/request.py in _open(self, req, data)
    543         result = self._call_chain(self.handle_open, protocol, protocol +
--> 544                                   '_open', req)
    545         if result:

/usr/lib/python3.6/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    503             func = getattr(handler, meth_name)
--> 504             result = func(*args)
    505             if result is not None:

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

/usr/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1319             except OSError as err: # timeout error
-> 1320                 raise URLError(err)
   1321             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)
    215         logger.debug("%s.geocode: %s", self.__class__.__name__, url)
    216         return self._parse_json(
--> 217             self._call_geocoder(url, timeout=timeout), exactly_one
    218         )
    219 

/usr/lib/python3/dist-packages/geopy/geocoders/base.py in _call_geocoder(self, url, timeout, raw, requester, deserializer, **kwargs)
    169                 if "timed out" in message:
    170                     raise GeocoderTimedOut('Service timed out')
--> 171             raise GeocoderServiceError(message)
    172 
    173         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.