Cartopy: Error when using gtiles?

Created on 2 Apr 2016  路  11Comments  路  Source: SciTools/cartopy

The following code raises an error:

proj = ccrs.PlateCarree()
ax = plt.axes(projection=proj)
#ax.stock_img() # with this instead of gtiles, it works
gg_tiles = GoogleTiles()
ax.add_image(gg_tiles, 10)
ax.plot([1,2], [1,2])
[<matplotlib.lines.Line2D at 0xb241358>]
Error in callback <function install_repl_displayhook.<locals>.post_execute at 0x0000000007EE0158> (for post_execute):
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\pyplot.py in post_execute()
    145             def post_execute():
    146                 if matplotlib.is_interactive():
--> 147                     draw_all()
    148 
    149             # IPython >= 2

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\_pylab_helpers.py in draw_all(cls, force)
    148         for f_mgr in cls.get_all_fig_managers():
    149             if force or f_mgr.canvas.figure.stale:
--> 150                 f_mgr.canvas.draw_idle()
    151 
    152 atexit.register(Gcf.destroy_all)

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\backend_bases.py in draw_idle(self, *args, **kwargs)
   2024         if not self._is_idle_drawing:
   2025             with self._idle_draw_cntx():
-> 2026                 self.draw(*args, **kwargs)
   2027 
   2028     def draw_cursor(self, event):

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\backends\backend_agg.py in draw(self)
    472 
    473         try:
--> 474             self.figure.draw(self.renderer)
    475         finally:
    476             RendererAgg.lock.release()

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     59     def draw_wrapper(artist, renderer, *args, **kwargs):
     60         before(artist, renderer)
---> 61         draw(artist, renderer, *args, **kwargs)
     62         after(artist, renderer)
     63 

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\figure.py in draw(self, renderer)
   1157         dsu.sort(key=itemgetter(0))
   1158         for zorder, a, func, args in dsu:
-> 1159             func(*args)
   1160 
   1161         renderer.close_group('figure')

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     59     def draw_wrapper(artist, renderer, *args, **kwargs):
     60         before(artist, renderer)
---> 61         draw(artist, renderer, *args, **kwargs)
     62         after(artist, renderer)
     63 

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\mpl\geoaxes.py in draw(self, renderer, inframe)
    352             for factory, args, kwargs in self.img_factories:
    353                 img, extent, origin = factory.image_for_domain(
--> 354                     self._get_extent_geom(factory.crs), args[0])
    355                 self.imshow(img, extent=extent, origin=origin,
    356                             transform=factory.crs, *args[1:], **kwargs)

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\io\img_tiles.py in image_for_domain(self, target_domain, target_z)
     86             tiles.append([img, x, y, origin])
     87 
---> 88         img, extent, origin = _merge_tiles(tiles)
     89         return img, extent, origin
     90 

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\io\img_tiles.py in _merge_tiles(tiles)
    382     """Return a single image, merging the given images."""
    383     if not tiles:
--> 384         raise ValueError('A non-empty list of tiles should '
    385                          'be provided to merge.')
    386     xset = [set(x) for i, x, y, _ in tiles]

ValueError: A non-empty list of tiles should be provided to merge.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
C:\portabel\miniconda\envs\zalando\lib\site-packages\IPython\core\formatters.py in __call__(self, obj)
    337                 pass
    338             else:
--> 339                 return printer(obj)
    340             # Finally look for special method names
    341             method = _safe_get_formatter_method(obj, self.print_method)

C:\portabel\miniconda\envs\zalando\lib\site-packages\IPython\core\pylabtools.py in <lambda>(fig)
    224 
    225     if 'png' in formats:
--> 226         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
    227     if 'retina' in formats or 'png2x' in formats:
    228         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))

C:\portabel\miniconda\envs\zalando\lib\site-packages\IPython\core\pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
    115 
    116     bytes_io = BytesIO()
--> 117     fig.canvas.print_figure(bytes_io, **kw)
    118     data = bytes_io.getvalue()
    119     if fmt == 'svg':

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
   2178                     orientation=orientation,
   2179                     dryrun=True,
-> 2180                     **kwargs)
   2181                 renderer = self.figure._cachedRenderer
   2182                 bbox_inches = self.figure.get_tightbbox(renderer)

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\backends\backend_agg.py in print_png(self, filename_or_obj, *args, **kwargs)
    525 
    526     def print_png(self, filename_or_obj, *args, **kwargs):
--> 527         FigureCanvasAgg.draw(self)
    528         renderer = self.get_renderer()
    529         original_dpi = renderer.dpi

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\backends\backend_agg.py in draw(self)
    472 
    473         try:
--> 474             self.figure.draw(self.renderer)
    475         finally:
    476             RendererAgg.lock.release()

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     59     def draw_wrapper(artist, renderer, *args, **kwargs):
     60         before(artist, renderer)
---> 61         draw(artist, renderer, *args, **kwargs)
     62         after(artist, renderer)
     63 

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\figure.py in draw(self, renderer)
   1157         dsu.sort(key=itemgetter(0))
   1158         for zorder, a, func, args in dsu:
-> 1159             func(*args)
   1160 
   1161         renderer.close_group('figure')

C:\portabel\miniconda\envs\zalando\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     59     def draw_wrapper(artist, renderer, *args, **kwargs):
     60         before(artist, renderer)
---> 61         draw(artist, renderer, *args, **kwargs)
     62         after(artist, renderer)
     63 

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\mpl\geoaxes.py in draw(self, renderer, inframe)
    352             for factory, args, kwargs in self.img_factories:
    353                 img, extent, origin = factory.image_for_domain(
--> 354                     self._get_extent_geom(factory.crs), args[0])
    355                 self.imshow(img, extent=extent, origin=origin,
    356                             transform=factory.crs, *args[1:], **kwargs)

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\io\img_tiles.py in image_for_domain(self, target_domain, target_z)
     86             tiles.append([img, x, y, origin])
     87 
---> 88         img, extent, origin = _merge_tiles(tiles)
     89         return img, extent, origin
     90 

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\io\img_tiles.py in _merge_tiles(tiles)
    382     """Return a single image, merging the given images."""
    383     if not tiles:
--> 384         raise ValueError('A non-empty list of tiles should '
    385                          'be provided to merge.')
    386     xset = [set(x) for i, x, y, _ in tiles]

ValueError: A non-empty list of tiles should be provided to merge.

<matplotlib.figure.Figure at 0x9181a58>

[ipython notebook, cartopy 0.14, py3.5 -> from the conda-forge channel as of today... Code example from here: http://www.geophysique.be/2014/02/25/shaded-relief-map-in-python/]

Most helpful comment

@michielbakker Yes old topic but we had the same issue yesterday and we found what's wrong (for us).

Here is the explanation which could help others :

We are developing a script which use cartopy and tiles direct access. But unfortunately Google does not allow tiles direct access. We must use their API ! When you try to access tiles directly, after a certain amount of time they ban your public IP address. That's why even if you try to load Google Maps with a browser, it does not work.

You can confirm this diagnostic by inspecting network requests in your browser. If you have been banned, you should see error 403 with this response :

We're sorry...... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.

See Google Help for more information.

Hope it helps

All 11 comments

This seems to work fine for me; maybe it failed to download?

Just tried again, still failing. If so, it should raise a different error?

Ok, digging a bit in, I get this:

t = GoogleTiles()
list(t.find_images(ax._get_extent_geom(t.crs), 10))
# -> returns the following tile:
t.get_image((512, 511, 10))
SSLError                                  Traceback (most recent call last)
C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1239             try:
-> 1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error

C:\portabel\miniconda\envs\zalando\lib\http\client.py in request(self, method, url, body, headers)
   1082         """Send a complete request to the server."""
-> 1083         self._send_request(method, url, body, headers)
   1084 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in _send_request(self, method, url, body, headers)
   1127             body = body.encode('iso-8859-1')
-> 1128         self.endheaders(body)
   1129 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in endheaders(self, message_body)
   1078             raise CannotSendHeader()
-> 1079         self._send_output(message_body)
   1080 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in _send_output(self, message_body)
    910 
--> 911         self.send(msg)
    912         if message_body is not None:

C:\portabel\miniconda\envs\zalando\lib\http\client.py in send(self, data)
    853             if self.auto_open:
--> 854                 self.connect()
    855             else:

C:\portabel\miniconda\envs\zalando\lib\http\client.py in connect(self)
   1236             self.sock = self._context.wrap_socket(self.sock,
-> 1237                                                   server_hostname=server_hostname)
   1238             if not self._context.check_hostname and self._check_hostname:

C:\portabel\miniconda\envs\zalando\lib\ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname)
    375                          server_hostname=server_hostname,
--> 376                          _context=self)
    377 

C:\portabel\miniconda\envs\zalando\lib\ssl.py in __init__(self, sock, keyfile, certfile, server_side, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, family, type, proto, fileno, suppress_ragged_eofs, npn_protocols, ciphers, server_hostname, _context)
    746                         raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
--> 747                     self.do_handshake()
    748 

C:\portabel\miniconda\envs\zalando\lib\ssl.py in do_handshake(self, block)
    982                 self.settimeout(None)
--> 983             self._sslobj.do_handshake()
    984         finally:

C:\portabel\miniconda\envs\zalando\lib\ssl.py in do_handshake(self)
    627         """Start the SSL/TLS handshake."""
--> 628         self._sslobj.do_handshake()
    629         if self.context.check_hostname:

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
<ipython-input-38-ce535e12e98a> in <module>()
----> 1 t.get_image((512, 511, 10))

C:\portabel\miniconda\envs\zalando\lib\site-packages\cartopy\io\img_tiles.py in get_image(self, tile)
    190         url = self._image_url(tile)
    191 
--> 192         fh = urlopen(url)
    193         im_data = six.BytesIO(fh.read())
    194         fh.close()

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    160     else:
    161         opener = _opener
--> 162     return opener.open(url, data, timeout)
    163 
    164 def install_opener(opener):

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in open(self, fullurl, data, timeout)
    463             req = meth(req)
    464 
--> 465         response = self._open(req, data)
    466 
    467         # post-process response

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in _open(self, req, data)
    481         protocol = req.type
    482         result = self._call_chain(self.handle_open, protocol, protocol +
--> 483                                   '_open', req)
    484         if result:
    485             return result

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in _call_chain(self, chain, kind, meth_name, *args)
    441         for handler in handlers:
    442             func = getattr(handler, meth_name)
--> 443             result = func(*args)
    444             if result is not None:
    445                 return result

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in https_open(self, req)
   1281         def https_open(self, req):
   1282             return self.do_open(http.client.HTTPSConnection, req,
-> 1283                 context=self._context, check_hostname=self._check_hostname)
   1284 
   1285         https_request = AbstractHTTPHandler.do_request_

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error
-> 1242                 raise URLError(err)
   1243             r = h.getresponse()
   1244         except:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)>

This error is masked in this line:
https://github.com/SciTools/cartopy/blob/master/lib/cartopy/io/img_tiles.py#L81

A workaround (and a bad one!) is this:

import ssl
if hasattr(ssl, '_create_unverified_context'):
    ssl._create_default_https_context = ssl._create_unverified_context
import cartopy.io.img_tiles as cimgt
t = cimgt.GoogleTiles()
t.get_image((512, 511, 10))

And now I get this:

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in http_error_default(self, req, fp, code, msg, hdrs)
    587 class HTTPDefaultErrorHandler(BaseHandler):
    588     def http_error_default(self, req, fp, code, msg, hdrs):
--> 589         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    590 
    591 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 403: Forbidden

And I don't even get tiles on maps.google.com... Not fun... :-/

Seems that google tiles is not the best choice...

Are you able to download anything with urlopen? This looks remarkably similar to a miniconda bug from over a year ago which didn't have a suitably built openssl.

This at least works:

import urllib.request
response = urllib.request.urlopen('https://www.example.com/')
html = response.read()
html

But this errors:

import urllib.request
response = urllib.request.urlopen('https://www.google.com/')
html = response.read()
html
SSLError                                  Traceback (most recent call last)
C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1239             try:
-> 1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error

C:\portabel\miniconda\envs\zalando\lib\http\client.py in request(self, method, url, body, headers)
   1082         """Send a complete request to the server."""
-> 1083         self._send_request(method, url, body, headers)
   1084 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in _send_request(self, method, url, body, headers)
   1127             body = body.encode('iso-8859-1')
-> 1128         self.endheaders(body)
   1129 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in endheaders(self, message_body)
   1078             raise CannotSendHeader()
-> 1079         self._send_output(message_body)
   1080 

C:\portabel\miniconda\envs\zalando\lib\http\client.py in _send_output(self, message_body)
    910 
--> 911         self.send(msg)
    912         if message_body is not None:

C:\portabel\miniconda\envs\zalando\lib\http\client.py in send(self, data)
    853             if self.auto_open:
--> 854                 self.connect()
    855             else:

C:\portabel\miniconda\envs\zalando\lib\http\client.py in connect(self)
   1236             self.sock = self._context.wrap_socket(self.sock,
-> 1237                                                   server_hostname=server_hostname)
   1238             if not self._context.check_hostname and self._check_hostname:

C:\portabel\miniconda\envs\zalando\lib\ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname)
    375                          server_hostname=server_hostname,
--> 376                          _context=self)
    377 

C:\portabel\miniconda\envs\zalando\lib\ssl.py in __init__(self, sock, keyfile, certfile, server_side, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, family, type, proto, fileno, suppress_ragged_eofs, npn_protocols, ciphers, server_hostname, _context)
    746                         raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
--> 747                     self.do_handshake()
    748 

C:\portabel\miniconda\envs\zalando\lib\ssl.py in do_handshake(self, block)
    982                 self.settimeout(None)
--> 983             self._sslobj.do_handshake()
    984         finally:

C:\portabel\miniconda\envs\zalando\lib\ssl.py in do_handshake(self)
    627         """Start the SSL/TLS handshake."""
--> 628         self._sslobj.do_handshake()
    629         if self.context.check_hostname:

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
<ipython-input-3-d092df22f256> in <module>()
      1 import urllib.request
----> 2 response = urllib.request.urlopen('https://www.google.com/')
      3 html = response.read()
      4 html

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    160     else:
    161         opener = _opener
--> 162     return opener.open(url, data, timeout)
    163 
    164 def install_opener(opener):

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in open(self, fullurl, data, timeout)
    463             req = meth(req)
    464 
--> 465         response = self._open(req, data)
    466 
    467         # post-process response

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in _open(self, req, data)
    481         protocol = req.type
    482         result = self._call_chain(self.handle_open, protocol, protocol +
--> 483                                   '_open', req)
    484         if result:
    485             return result

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in _call_chain(self, chain, kind, meth_name, *args)
    441         for handler in handlers:
    442             func = getattr(handler, meth_name)
--> 443             result = func(*args)
    444             if result is not None:
    445                 return result

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in https_open(self, req)
   1281         def https_open(self, req):
   1282             return self.do_open(http.client.HTTPSConnection, req,
-> 1283                 context=self._context, check_hostname=self._check_hostname)
   1284 
   1285         https_request = AbstractHTTPHandler.do_request_

C:\portabel\miniconda\envs\zalando\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error
-> 1242                 raise URLError(err)
   1243             r = h.getresponse()
   1244         except:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)>
[zalando] 位 conda list
# packages in environment at C:\portabel\miniconda\envs\zalando:
#
bzip2                     1.0.6                    vc14_2  [vc14]  defaults
cartopy                   0.14.0              np110py35_1    conda-forge
certifi                   2015.9.6.2               py35_0    defaults
cffi                      1.5.2                    py35_0    defaults
cryptography              1.3                      py35_0    defaults
cycler                    0.10.0                   py35_0    conda-forge
decorator                 4.0.9                    py35_0    defaults
descartes                 1.0.2                    py35_0    conda-forge
freetype                  2.5.5                    vc14_0  [vc14]  defaults
funcsigs                  0.4                      py35_0    defaults
geopy                     1.11.0                   py35_0    ioos
geos                      3.4.2                    vc14_1  [vc14]  conda-forge
haversine                 0.4.5                    py35_0    conda-forge
idna                      2.0                      py35_0    defaults
ipykernel                 4.3.1                    py35_0    defaults
ipython                   4.1.2                    py35_1    defaults
ipython-genutils          0.1.0                     <pip>
ipython_genutils          0.1.0                    py35_0    defaults
jpeg                      8d                       vc14_0  [vc14]  defaults
jupyter-client            4.2.2                     <pip>
jupyter-core              4.1.0                     <pip>
jupyter_client            4.2.2                    py35_0    defaults
jupyter_core              4.1.0                    py35_0    defaults
libpng                    1.6.17                   vc14_1  [vc14]  defaults
libtiff                   4.0.6                    vc14_1  [vc14]  defaults
lxml                      3.6.0                    py35_0    defaults
matplotlib                1.5.1               np110py35_0    defaults
mkl                       11.3.1                        0    defaults
mock                      1.3.0                    py35_0    defaults
nose                      1.3.7                    py35_0    defaults
numpy                     1.10.4                   py35_0    defaults
openssl                   1.0.2g                   vc14_0  [vc14]  defaults
owslib                    0.10.3                   py35_0    conda-forge
pandas                    0.18.0              np110py35_0    defaults
path.py                   8.1.2                    py35_1    defaults
pbr                       1.3.0                    py35_0    defaults
pickleshare               0.5                      py35_0    defaults
pillow                    3.1.1                    py35_0    defaults
pip                       8.1.1                    py35_1    defaults
proj.4                    4.9.1               py35_vc14_2  [vc14]  conda-forge
pyasn1                    0.1.9                    py35_0    defaults
pycparser                 2.14                     py35_0    defaults
pyepsg                    0.2.0                    py35_0    conda-forge
pyparsing                 2.0.3                    py35_0    defaults
pyproj                    1.9.5.1                  py35_0    conda-forge
pyqt                      4.11.4                   py35_5    defaults
pyreadline                2.1                      py35_0    defaults
pyshp                     1.2.3                    py35_0    conda-forge
python                    3.5.1                         4    defaults
python-dateutil           2.5.1                    py35_0    defaults
pytz                      2016.3                   py35_0    defaults
pyzmq                     15.2.0                   py35_0    defaults
qt                        4.8.7                    vc14_7  [vc14]  defaults
requests                  2.9.1                    py35_0    defaults
scipy                     0.17.0              np110py35_0    defaults
setuptools                20.3                     py35_0    defaults
shapely                   1.5.13              np110py35_1    conda-forge
simplegeneric             0.8.1                    py35_0    defaults
sip                       4.16.9                   py35_2    defaults
six                       1.10.0                   py35_0    defaults
sphinx                    1.3.1                     <pip>
tk                        8.5.18                   vc14_0  [vc14]  defaults
tornado                   4.3                      py35_0    defaults
traitlets                 4.2.1                    py35_0    defaults
vs2015_runtime            14.00.23026.0                 0    defaults
wheel                     0.29.0                   py35_0    defaults
zlib                      1.2.8                    vc14_2  [vc14]  defaults

This isn't a cartopy issue, but may be something that has been fixed if you were to use conda-forge's certifi. In the interest of keeping the issue tracker clean, I'm going to close this issue. If you don't find a solution @janschulz, I'd consider raising an issue on the certifi-feedstock.

Thanks!

Hi, it's an old topic but had the same problem and now sort of fixed it. For me, when I get this issue it means that the google api is actually blocking me. If I go to google maps via my browser I also get an error. However, if I switch wifi networks or wait long enough google maps via browser and via cartopy both work again.

@michielbakker Yes old topic but we had the same issue yesterday and we found what's wrong (for us).

Here is the explanation which could help others :

We are developing a script which use cartopy and tiles direct access. But unfortunately Google does not allow tiles direct access. We must use their API ! When you try to access tiles directly, after a certain amount of time they ban your public IP address. That's why even if you try to load Google Maps with a browser, it does not work.

You can confirm this diagnostic by inspecting network requests in your browser. If you have been banned, you should see error 403 with this response :

We're sorry...... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.

See Google Help for more information.

Hope it helps

Is there any way of specifying Google Maps API key? @eric-taix

Sometimes we must set a headers for our request and it worked for me.

    def get_image(self, tile):
        if six.PY3:
            from urllib.request import urlopen, Request
        else:
            from urllib2 import urlopen, Request

        url = self._image_url(tile)

        if self.headers is not None:
            req = Request(url, headers=self.headers)
        else:
            req = Request(url)
        fh = urlopen(req)
        im_data = six.BytesIO(fh.read())
        fh.close()
        img = Image.open(im_data)

        img = img.convert(self.desired_tile_form)

        return img, self.tileextent(tile), 'lower'

copy the headers from chrome like this:

{'Host': '***',
 'Connection': 'keep-alive',
 'Pragma': 'no-cache',
 'Cache-Control': 'no-cache',
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
 'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
 'Sec-Fetch-Site': 'same-site',
 'Sec-Fetch-Mode': 'no-cors',
 'Referer': 'https://****/',
 'Accept-Encoding': 'gzip, deflate, br',
 'Accept-Language': '**',
}
Was this page helpful?
0 / 5 - 0 ratings