-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Thank you for a helpful library!
Environment Information
| OS | Linux (Ubuntu 24.04) | CPU(s) | 16 | Machine | x86_64 |
|---|---|---|---|---|---|
| Architecture | 64bit | RAM | 23.5 GiB | Environment | Jupyter |
| File system | ext4 | ||||
| Python 3.12.3 (main, Jan 22 2026, 20:57:42) [GCC 13.3.0] | |||||
| geemap | 0.37.1 | ee | 1.7.16 | ipyleaflet | 0.20.0 |
| folium | 0.20.0 | jupyterlab | Module not found | notebook | Module not found |
| ipyevents | 2.0.2 | geopandas | 1.1.1 | localtileserver | 0.10.6 |
Description
As far as I can tell, this bug is only triggered in a Jupyter notebook, which I edit and run in VSCode.
I run this from within EU, where there are restrictions on parts of the Google Maps API.
In my project directory, I have an .env file with different api keys, also GOOGLE_MAPS_API_KEY. VSCode helpfully expands these into the environment for Jupyter files, and geemap helpfully picks this up when the .Map() instance is created.
Thus, Google returns a 403 error, and geemaps.Map() fails, even when I explicitly try to use other data.
A workaround is to remove GOOGLE_MAPS_API_KEY from os.environ before geemap.Map() is invoked. See the attached html: test_geemap_gmaps.html
The culprit is coreutils.get_google_maps_api_key() being run from _get_available_basemaps() (see full error below).
I would love to see an explicit option, maybe
geemap.Map(use_google_tiles=False)
or at least a warning about GOOGLE_MAPS_API_KEY being set, if the geemap.Map() fails with 403.
(A warning would be helpful for developers, but not so much for the end-user of a distributed script.)
Let me know if I should follow up with a proposed patch. Thanks!
What I Did
import ee
import sys
import os
import platform
print(f"Python version: {sys.version}")
print(f"Platform: {platform.platform()}")
print(f"Geemap version: {geemap.__version__}")
for key, value in os.environ.items():
if "GOOGLE" in key or "EE" in key:
print(f"{key}: {'*' * len(value)}")
# Authenticate Earth Engine
ee.Authenticate()
# load project id from environment variable
PROJECT_ID = os.getenv("GEE_PROJECT_ID")
# Initialize the Earth Engine module.
ee.Initialize(project=PROJECT_ID)
# Create map instance
Map = geemap.Map(basemap="Esri.WorldImagery")Output:
Python version: 3.12.3 (main, Jan 22 2026, 20:57:42) [GCC 13.3.0]
Platform: Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.39
Geemap version: 0.37.1
GOOGLE_MAPS_API_KEY: ***************************************
GEE_PROJECT_ID: ************
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[1], [line 28](vscode-notebook-cell:?execution_count=1&line=28)
25 ee.Initialize(project=PROJECT_ID)
27 # Create map instance
---> [28](vscode-notebook-cell:?execution_count=1&line=28) Map = geemap.Map(basemap="Esri.WorldImagery")
File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/geemap.py:141, in Map.__init__(self, **kwargs)
139 self._USER_AGENT_PREFIX = "geemap"
140 self.kwargs = kwargs
--> [141](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/geemap.py:141) super().__init__(**kwargs)
142 self._var_name = "Map" # The Map variable name for converting JS to Python
144 if kwargs.get("height"):
File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:634, in Map.__init__(self, **kwargs)
628 def __init__(self, **kwargs: Any) -> None:
629 """Initialize the map with given keyword arguments.
630
631 Args:
632 **kwargs: Additional keyword arguments for the map.
633 """
--> [634](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:634) self._available_basemaps = self._get_available_basemaps()
636 # Use the first basemap in the list of available basemaps.
637 if "basemap" not in kwargs:
File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:1356, in Map._get_available_basemaps(self)
1353 tile_providers = list(basemaps.get_xyz_dict().values())
1354 if coreutils.get_google_maps_api_key():
1355 tile_providers = tile_providers + list(
-> [1356](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:1356) basemaps.get_google_map_tile_providers().values()
1357 )
1359 ret_dict = {}
1360 for tile_info in tile_providers:
File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:376, in get_google_map_tile_providers(language, region, api_key, **kwargs)
373 gmap_providers = {}
375 for m_type in GoogleMapsTileProvider.MAP_TYPE_CONFIG:
--> [376](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:376) gmap_providers[m_type] = GoogleMapsTileProvider(
377 map_type=m_type, language=language, region=region, api_key=api_key, **kwargs
378 )
380 return gmap_providers
File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:343, in GoogleMapsTileProvider.__init__(self, map_type, language, region, api_key, **kwargs)
332 super().__init__(
333 {
334 "url": f"https://tile.googleapis.com/v1/2dtiles/{{z}}/{{x}}/{{y}}?session={json['session']}&key={{accessToken}}",
(...) 340 }
341 )
342 else:
--> [343](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:343) raise RuntimeError(
344 f"Error creating a Maps API session:\n{response.json()}."
345 )
RuntimeError: Error creating a Maps API session:
{'error': {'code': 403, 'message': 'Your request cannot be served because satellite tiles and 3D tiles are not available for your account and region. Learn more here: https://developers.google.com/maps/comms/eea/map-tiles.', 'errors': [{'message': 'Your request cannot be served because satellite tiles and 3D tiles are not available for your account and region. Learn more here: https://developers.google.com/maps/comms/eea/map-tiles.', 'domain': 'global', 'reason': 'forbidden'}], 'status': 'PERMISSION_DENIED'}}.