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/]
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': '**',
}
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 :
Hope it helps