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]: import geodatasets
In [2]: boros = geopandas.read_file(geodatasets.get_path("nybb"))
In [3]: boros.BoroName
Out[3]:
0 Staten Island
1 Queens
2 Brooklyn
3 Manhattan
4 Bronx
Name: BoroName, dtype: object
In [4]: boro_locations = geopandas.tools.geocode(boros.BoroName)
---------------------------------------------------------------------------
TimeoutError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:536, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
535 try:
--> 536 response = conn.getresponse()
537 except (BaseSSLError, OSError) as e:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connection.py:461, in HTTPConnection.getresponse(self)
460 # Get the response from http.client.HTTPConnection
--> 461 httplib_response = super().getresponse()
463 try:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/http/client.py:1378, in HTTPConnection.getresponse(self)
1377 try:
-> 1378 response.begin()
1379 except ConnectionError:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/http/client.py:318, in HTTPResponse.begin(self)
317 while True:
--> 318 version, status, reason = self._read_status()
319 if status != CONTINUE:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/http/client.py:279, in HTTPResponse._read_status(self)
278 def _read_status(self):
--> 279 line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
280 if len(line) > _MAXLINE:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/socket.py:706, in SocketIO.readinto(self, b)
705 try:
--> 706 return self._sock.recv_into(b)
707 except timeout:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/ssl.py:1311, in SSLSocket.recv_into(self, buffer, nbytes, flags)
1308 raise ValueError(
1309 "non-zero flags not allowed in calls to recv_into() on %s" %
1310 self.__class__)
-> 1311 return self.read(nbytes, buffer)
1312 else:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/ssl.py:1167, in SSLSocket.read(self, len, buffer)
1166 if buffer is not None:
-> 1167 return self._sslobj.read(len, buffer)
1168 else:
TimeoutError: The read operation timed out
The above exception was the direct cause of the following exception:
ReadTimeoutError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:790, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
789 # Make the request on the HTTPConnection object
--> 790 response = self._make_request(
791 conn,
792 method,
793 url,
794 timeout=timeout_obj,
795 body=body,
796 headers=headers,
797 chunked=chunked,
798 retries=retries,
799 response_conn=response_conn,
800 preload_content=preload_content,
801 decode_content=decode_content,
802 **response_kw,
803 )
805 # Everything went great!
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:538, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
537 except (BaseSSLError, OSError) as e:
--> 538 self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
539 raise
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:370, in HTTPConnectionPool._raise_timeout(self, err, url, timeout_value)
369 if isinstance(err, SocketTimeout):
--> 370 raise ReadTimeoutError(
371 self, url, f"Read timed out. (read timeout={timeout_value})"
372 ) from err
374 # See the above comment about EAGAIN in Python 3.
ReadTimeoutError: HTTPSConnectionPool(host='photon.komoot.io', port=443): Read timed out. (read timeout=1)
The above exception was the direct cause of the following exception:
MaxRetryError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/requests/adapters.py:486, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
485 try:
--> 486 resp = conn.urlopen(
487 method=request.method,
488 url=url,
489 body=request.body,
490 headers=request.headers,
491 redirect=False,
492 assert_same_host=False,
493 preload_content=False,
494 decode_content=False,
495 retries=self.max_retries,
496 timeout=timeout,
497 chunked=chunked,
498 )
500 except (ProtocolError, OSError) as err:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:874, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
871 log.warning(
872 "Retrying (%r) after connection broken by '%r': %s", retries, err, url
873 )
--> 874 return self.urlopen(
875 method,
876 url,
877 body,
878 headers,
879 retries,
880 redirect,
881 assert_same_host,
882 timeout=timeout,
883 pool_timeout=pool_timeout,
884 release_conn=release_conn,
885 chunked=chunked,
886 body_pos=body_pos,
887 preload_content=preload_content,
888 decode_content=decode_content,
889 **response_kw,
890 )
892 # Handle redirect?
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:874, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
871 log.warning(
872 "Retrying (%r) after connection broken by '%r': %s", retries, err, url
873 )
--> 874 return self.urlopen(
875 method,
876 url,
877 body,
878 headers,
879 retries,
880 redirect,
881 assert_same_host,
882 timeout=timeout,
883 pool_timeout=pool_timeout,
884 release_conn=release_conn,
885 chunked=chunked,
886 body_pos=body_pos,
887 preload_content=preload_content,
888 decode_content=decode_content,
889 **response_kw,
890 )
892 # Handle redirect?
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/connectionpool.py:844, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
842 new_e = ProtocolError("Connection aborted.", new_e)
--> 844 retries = retries.increment(
845 method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
846 )
847 retries.sleep()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/urllib3/util/retry.py:515, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
514 reason = error or ResponseError(cause)
--> 515 raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
517 log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
MaxRetryError: HTTPSConnectionPool(host='photon.komoot.io', port=443): Max retries exceeded with url: /api?q=Staten+Island&limit=1 (Caused by ReadTimeoutError("HTTPSConnectionPool(host='photon.komoot.io', port=443): Read timed out. (read timeout=1)"))
During handling of the above exception, another exception occurred:
ConnectionError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/geopy/adapters.py:482, in RequestsAdapter._request(self, url, timeout, headers)
481 try:
--> 482 resp = self.session.get(url, timeout=timeout, headers=headers)
483 except Exception as error:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/requests/sessions.py:602, in Session.get(self, url, **kwargs)
601 kwargs.setdefault("allow_redirects", True)
--> 602 return self.request("GET", url, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/requests/sessions.py:589, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
588 send_kwargs.update(settings)
--> 589 resp = self.send(prep, **send_kwargs)
591 return resp
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/requests/sessions.py:703, in Session.send(self, request, **kwargs)
702 # Send the request
--> 703 r = adapter.send(request, **kwargs)
705 # Total elapsed time of the request (approximately)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/requests/adapters.py:519, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
517 raise SSLError(e, request=request)
--> 519 raise ConnectionError(e, request=request)
521 except ClosedPoolError as e:
ConnectionError: HTTPSConnectionPool(host='photon.komoot.io', port=443): Max retries exceeded with url: /api?q=Staten+Island&limit=1 (Caused by ReadTimeoutError("HTTPSConnectionPool(host='photon.komoot.io', port=443): Read timed out. (read timeout=1)"))
During handling of the above exception, another exception occurred:
GeocoderUnavailable Traceback (most recent call last)
Cell In[4], line 1
----> 1 boro_locations = geopandas.tools.geocode(boros.BoroName)
File ~/checkouts/readthedocs.org/user_builds/geopandas/checkouts/v0.14.0/geopandas/tools/geocoding.py:67, in geocode(strings, provider, **kwargs)
64 provider = "photon"
65 throttle_time = _get_throttle_time(provider)
---> 67 return _query(strings, True, provider, throttle_time, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/checkouts/v0.14.0/geopandas/tools/geocoding.py:141, in _query(data, forward, provider, throttle_time, **kwargs)
139 try:
140 if forward:
--> 141 results[i] = coder.geocode(s)
142 else:
143 results[i] = coder.reverse((s.y, s.x), exactly_one=True)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/geopy/geocoders/photon.py:166, in Photon.geocode(self, query, exactly_one, timeout, location_bias, language, limit, osm_tag, bbox)
164 logger.debug("%s.geocode: %s", self.__class__.__name__, url)
165 callback = partial(self._parse_json, exactly_one=exactly_one)
--> 166 return self._call_geocoder(url, callback, timeout=timeout)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/geopy/geocoders/base.py:368, in Geocoder._call_geocoder(self, url, callback, timeout, is_json, headers)
366 try:
367 if is_json:
--> 368 result = self.adapter.get_json(url, timeout=timeout, headers=req_headers)
369 else:
370 result = self.adapter.get_text(url, timeout=timeout, headers=req_headers)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/geopy/adapters.py:472, in RequestsAdapter.get_json(self, url, timeout, headers)
471 def get_json(self, url, *, timeout, headers):
--> 472 resp = self._request(url, timeout=timeout, headers=headers)
473 try:
474 return resp.json()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.14.0/lib/python3.11/site-packages/geopy/adapters.py:494, in RequestsAdapter._request(self, url, timeout, headers)
492 raise GeocoderServiceError(message)
493 else:
--> 494 raise GeocoderUnavailable(message)
495 elif isinstance(error, requests.Timeout):
496 raise GeocoderTimedOut("Service timed out")
GeocoderUnavailable: HTTPSConnectionPool(host='photon.komoot.io', port=443): Max retries exceeded with url: /api?q=Staten+Island&limit=1 (Caused by ReadTimeoutError("HTTPSConnectionPool(host='photon.komoot.io', port=443): Read timed out. (read timeout=1)"))
In [5]: boro_locations
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 1
----> 1 boro_locations
NameError: name 'boro_locations' is not defined
In [6]: import matplotlib.pyplot as plt
In [7]: fig, ax = plt.subplots()
In [8]: boros.to_crs("EPSG:4326").plot(ax=ax, color="white", edgecolor="black");
In [9]: boro_locations.plot(ax=ax, color="red");
By default, the geocode() function uses the
Photon geocoding API.
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 'photon' (the default), which expects fair usage
- extensive usage will be throttled.
(Photon’s Terms of Use).