Skip to content

basemaps module

Module for basemaps.

Each basemap is defined as an item in the basemaps dictionary.

More WMS basemaps can be found at the following websites:

  1. USGS National Map: https://viewer.nationalmap.gov/services/
  2. MRLC NLCD Land Cover data: https://viewer.nationalmap.gov/services/
  3. FWS NWI Wetlands data: https://www.fws.gov/wetlands/Data/Web-Map-Services.html

GoogleMapsTileProvider

Bases: TileProvider

Google Maps TileProvider.

Source code in geemap/basemaps.py
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
class GoogleMapsTileProvider(xyzservices.TileProvider):
    """Google Maps TileProvider."""

    MAP_TYPE_CONFIG = {
        "roadmap": {"mapType": "roadmap"},
        "satellite": {"mapType": "satellite"},
        "terrain": {
            "mapType": "terrain",
            "layerTypes": ["layerRoadmap"],
        },
        "hybrid": {
            "mapType": "satellite",
            "layerTypes": ["layerRoadmap"],
        },
    }

    def __init__(
        self,
        map_type: str = "roadmap",
        language: str = "en-Us",
        region: str = "US",
        api_key: str | None = None,
        **kwargs,
    ):
        """Generates Google Map tiles using the provided parameters.

        To get an API key and enable Map Tiles API, visit
        https://developers.google.com/maps/get-started#create-project.  You can set the
        API key using the environment variable `GOOGLE_MAPS_API_KEY` or by passing it as
        an argument.

        Args:
            map_type: The type of map to generate. Options are 'roadmap', 'satellite',
                'terrain', 'hybrid', 'traffic', 'streetview'.  Defaults to 'roadmap'.
            language: An IETF language tag that specifies the language used to display
                information on the tiles, such as 'zh-Cn'.  Defaults to 'en-Us'.
            region: A Common Locale Data Repository region identifier (two uppercase
                letters) that represents the physical location of the user. Defaults to
                'US'.
            api_key: The API key to use for the Google Maps API.  If not provided, it
                will try to get it from the environment or Colab user data with the key
                'GOOGLE_MAPS_API_KEY'. Defaults to None.
            **kwargs: Additional parameters to pass to the map generation. For more
                info, visit https://bit.ly/3UhbZKU

        Raises:
            ValueError: If the API key is not provided and cannot be found in the
                environment or Colab user data.
            ValueError: If the map_type is not one of the allowed types.

        Example:
            >>> from geemap.basemaps import GoogleMapsTileProvider
            >>> m = geemap.Map()
            >>> basemap = GoogleMapsTileProvider(map_type='roadmap',
                language="en-Us", region="US", scale="scaleFactor2x", highDpi=True)
            >>> m.add_basemap(basemap)
        """
        key = api_key or coreutils.get_google_maps_api_key()
        if key is None:
            raise ValueError(
                "API key is required to access Google Maps API. To get an API "
                "key and enable Map Tiles API, visit "
                "https://developers.google.com/maps/get-started#create-project"
            )

        if map_type not in self.MAP_TYPE_CONFIG:
            raise ValueError(f"map_type must be one of: {self.MAP_TYPE_CONFIG.keys()}")

        request_url = f"https://tile.googleapis.com/v1/createSession?key={key}"
        response = requests.post(
            url=request_url,
            headers={"Content-Type": "application/json"},
            json={
                **self.MAP_TYPE_CONFIG[map_type],
                "language": language,
                "region": region,
                **kwargs,
            },
            timeout=3,
        )

        if response.status_code == requests.codes.ok:
            json = response.json()
            map_name = map_type.capitalize()
            super().__init__(
                {
                    "url": f"https://tile.googleapis.com/v1/2dtiles/{{z}}/{{x}}/{{y}}?session={json['session']}&key={{accessToken}}",
                    "attribution": f"© Google {map_name}",
                    "accessToken": key,
                    "name": f"Google.{map_name}",
                    "ext": json["imageFormat"],
                    "tileSize": json["tileWidth"],
                }
            )
        else:
            raise RuntimeError(
                f"Error creating a Maps API session:\n{response.json()}."
            )

__init__(map_type='roadmap', language='en-Us', region='US', api_key=None, **kwargs)

Generates Google Map tiles using the provided parameters.

To get an API key and enable Map Tiles API, visit https://developers.google.com/maps/get-started#create-project. You can set the API key using the environment variable GOOGLE_MAPS_API_KEY or by passing it as an argument.

Parameters:

Name Type Description Default
map_type str

The type of map to generate. Options are 'roadmap', 'satellite', 'terrain', 'hybrid', 'traffic', 'streetview'. Defaults to 'roadmap'.

'roadmap'
language str

An IETF language tag that specifies the language used to display information on the tiles, such as 'zh-Cn'. Defaults to 'en-Us'.

'en-Us'
region str

A Common Locale Data Repository region identifier (two uppercase letters) that represents the physical location of the user. Defaults to 'US'.

'US'
api_key str | None

The API key to use for the Google Maps API. If not provided, it will try to get it from the environment or Colab user data with the key 'GOOGLE_MAPS_API_KEY'. Defaults to None.

None
**kwargs

Additional parameters to pass to the map generation. For more info, visit https://bit.ly/3UhbZKU

{}

Raises:

Type Description
ValueError

If the API key is not provided and cannot be found in the environment or Colab user data.

ValueError

If the map_type is not one of the allowed types.

Example

from geemap.basemaps import GoogleMapsTileProvider m = geemap.Map() basemap = GoogleMapsTileProvider(map_type='roadmap', language="en-Us", region="US", scale="scaleFactor2x", highDpi=True) m.add_basemap(basemap)

Source code in geemap/basemaps.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
def __init__(
    self,
    map_type: str = "roadmap",
    language: str = "en-Us",
    region: str = "US",
    api_key: str | None = None,
    **kwargs,
):
    """Generates Google Map tiles using the provided parameters.

    To get an API key and enable Map Tiles API, visit
    https://developers.google.com/maps/get-started#create-project.  You can set the
    API key using the environment variable `GOOGLE_MAPS_API_KEY` or by passing it as
    an argument.

    Args:
        map_type: The type of map to generate. Options are 'roadmap', 'satellite',
            'terrain', 'hybrid', 'traffic', 'streetview'.  Defaults to 'roadmap'.
        language: An IETF language tag that specifies the language used to display
            information on the tiles, such as 'zh-Cn'.  Defaults to 'en-Us'.
        region: A Common Locale Data Repository region identifier (two uppercase
            letters) that represents the physical location of the user. Defaults to
            'US'.
        api_key: The API key to use for the Google Maps API.  If not provided, it
            will try to get it from the environment or Colab user data with the key
            'GOOGLE_MAPS_API_KEY'. Defaults to None.
        **kwargs: Additional parameters to pass to the map generation. For more
            info, visit https://bit.ly/3UhbZKU

    Raises:
        ValueError: If the API key is not provided and cannot be found in the
            environment or Colab user data.
        ValueError: If the map_type is not one of the allowed types.

    Example:
        >>> from geemap.basemaps import GoogleMapsTileProvider
        >>> m = geemap.Map()
        >>> basemap = GoogleMapsTileProvider(map_type='roadmap',
            language="en-Us", region="US", scale="scaleFactor2x", highDpi=True)
        >>> m.add_basemap(basemap)
    """
    key = api_key or coreutils.get_google_maps_api_key()
    if key is None:
        raise ValueError(
            "API key is required to access Google Maps API. To get an API "
            "key and enable Map Tiles API, visit "
            "https://developers.google.com/maps/get-started#create-project"
        )

    if map_type not in self.MAP_TYPE_CONFIG:
        raise ValueError(f"map_type must be one of: {self.MAP_TYPE_CONFIG.keys()}")

    request_url = f"https://tile.googleapis.com/v1/createSession?key={key}"
    response = requests.post(
        url=request_url,
        headers={"Content-Type": "application/json"},
        json={
            **self.MAP_TYPE_CONFIG[map_type],
            "language": language,
            "region": region,
            **kwargs,
        },
        timeout=3,
    )

    if response.status_code == requests.codes.ok:
        json = response.json()
        map_name = map_type.capitalize()
        super().__init__(
            {
                "url": f"https://tile.googleapis.com/v1/2dtiles/{{z}}/{{x}}/{{y}}?session={json['session']}&key={{accessToken}}",
                "attribution": f"© Google {map_name}",
                "accessToken": key,
                "name": f"Google.{map_name}",
                "ext": json["imageFormat"],
                "tileSize": json["tileWidth"],
            }
        )
    else:
        raise RuntimeError(
            f"Error creating a Maps API session:\n{response.json()}."
        )

get_google_map_tile_providers(language='en-Us', region='US', api_key=None, **kwargs)

Generates a dictionary of Google Map tile providers for different map types.

Parameters:

Name Type Description Default
language str

An IETF language tag that specifies the language used to display information on the tiles, such as 'zh-Cn'. Defaults to 'en-Us'.

'en-Us'
region str

A Common Locale Data Repository region identifier (two uppercase letters) that represents the physical location of the user. Defaults to 'US'.

'US'
api_key str | None

The API key to use for the Google Maps API. If not provided, it will try to get it from the environment or Colab user data with the key 'GOOGLE_MAPS_API_KEY'. Defaults to None.

None
**kwargs

Additional parameters to pass to the map generation. For more info, visit https://bit.ly/3UhbZKU

{}

Returns:

Type Description
dict[str, Any]

A dictionary where the keys are the map types ('roadmap', 'satellite',

dict[str, Any]

'terrain', 'hybrid') and the values are the corresponding GoogleMapsTileProvider

dict[str, Any]

objects.

Source code in geemap/basemaps.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
def get_google_map_tile_providers(
    language: str = "en-Us",
    region: str = "US",
    api_key: str | None = None,
    **kwargs,
) -> dict[str, Any]:
    """Generates a dictionary of Google Map tile providers for different map types.

    Args:
        language: An IETF language tag that specifies the language used to display
            information on the tiles, such as 'zh-Cn'.  Defaults to 'en-Us'.
        region: A Common Locale Data Repository region identifier (two uppercase
            letters) that represents the physical location of the user. Defaults to
            'US'.
        api_key: The API key to use for the Google Maps API.  If not provided, it will
            try to get it from the environment or Colab user data with the key
            'GOOGLE_MAPS_API_KEY'. Defaults to None.
        **kwargs: Additional parameters to pass to the map generation. For more info,
            visit https://bit.ly/3UhbZKU

    Returns:
        A dictionary where the keys are the map types ('roadmap', 'satellite',
        'terrain', 'hybrid') and the values are the corresponding GoogleMapsTileProvider
        objects.
    """
    gmap_providers = {}

    for m_type in GoogleMapsTileProvider.MAP_TYPE_CONFIG:
        gmap_providers[m_type] = GoogleMapsTileProvider(
            map_type=m_type, language=language, region=region, api_key=api_key, **kwargs
        )

    return gmap_providers

get_xyz_dict(free_only=True, france=False)

Returns a dictionary of xyz services.

Parameters:

Name Type Description Default
free_only bool

Whether to return only free xyz tile services that do not require an access token. Defaults to True.

True
france bool

Whether to include Geoportail France basemaps. Defaults to False.

False

Returns:

Name Type Description
dict dict[str, Any]

A dictionary of xyz services.

Source code in geemap/basemaps.py
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
def get_xyz_dict(free_only: bool = True, france: bool = False) -> dict[str, Any]:
    """Returns a dictionary of xyz services.

    Args:
        free_only: Whether to return only free xyz tile services that do not require an
            access token. Defaults to True.

        france: Whether to include Geoportail France basemaps.  Defaults to False.

    Returns:
        dict: A dictionary of xyz services.

    """
    xyz_bunch = xyzservices.providers

    if free_only:
        xyz_bunch = xyz_bunch.filter(requires_token=False)
    if not france:
        xyz_bunch = xyz_bunch.filter(
            function=lambda tile: "france" not in dict(tile)["name"].lower()
        )

    xyz_dict = xyz_bunch.flatten()

    for key, value in xyz_dict.items():
        tile = xyzservices.TileProvider(value)
        if "type" not in tile:
            tile["type"] = "xyz"
        xyz_dict[key] = tile

    xyz_dict = collections.OrderedDict(sorted(xyz_dict.items()))
    return xyz_dict

qms_to_geemap(service_id)

Convert a qms service to an ipyleaflet tile layer.

Parameters:

Name Type Description Default
service_id str

Service ID.

required

Returns:

Type Description
TileLayer

An ipyleaflet tile layer.

Source code in geemap/basemaps.py
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
def qms_to_geemap(service_id: str) -> ipyleaflet.TileLayer:
    """Convert a qms service to an ipyleaflet tile layer.

    Args:
        service_id: Service ID.

    Returns:
        An ipyleaflet tile layer.
    """
    service_details = get_qms(service_id)
    name = service_details["name"]
    url = service_details["url"]
    attribution = service_details["copyright_text"]

    layer = ipyleaflet.TileLayer(url=url, name=name, attribution=attribution)
    return layer

search_qms(keywords, limit=10)

Search qms files for keywords.

Reference: https://github.com/geopandas/xyzservices/issues/65

Parameters:

Name Type Description Default
keywords str

Keywords to search for.

required
limit int

Number of results to return.

10
Source code in geemap/basemaps.py
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
def search_qms(keywords: str, limit: int = 10) -> list[Any] | None:
    """Search qms files for keywords.

    Reference: https://github.com/geopandas/xyzservices/issues/65

    Args:
        keywords: Keywords to search for.
        limit: Number of results to return.
    """
    QMS_API = "https://qms.nextgis.com/api/v1/geoservices"

    services = requests.get(
        f"{QMS_API}/?search={keywords}&type=tms&epsg=3857&limit={str(limit)}"
    )
    services = services.json()
    if services["count"] == 0:
        return None
    elif services["count"] <= limit:
        return services["results"]
    else:
        return services["results"][:limit]

xyz_to_folium()

Convert xyz tile services to folium tile layers.

Returns:

Name Type Description
dict dict[str, Any]

A dictionary of folium tile layers.

Source code in geemap/basemaps.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
def xyz_to_folium() -> dict[str, Any]:
    """Convert xyz tile services to folium tile layers.

    Returns:
        dict: A dictionary of folium tile layers.
    """
    folium_dict = {}
    # Ignore Esri basemaps if they are already in the custom XYZ_TILES.
    ignore_list = [XYZ_TILES[tile]["name"] for tile in XYZ_TILES]

    for key, tile in custom_tiles["xyz"].items():
        folium_dict[key] = folium.TileLayer(
            tiles=tile["url"],
            attr=tile["attribution"],
            name=tile["name"],
            overlay=True,
            control=True,
            max_zoom=30,
        )

    for key, tile in custom_tiles["wms"].items():
        folium_dict[key] = folium.WmsTileLayer(
            url=tile["url"],
            layers=tile["layers"],
            name=tile["name"],
            attr=tile["attribution"],
            fmt=tile["format"],
            transparent=tile["transparent"],
            overlay=True,
            control=True,
            max_zoom=30,
        )

    for item in get_xyz_dict().values():
        if item["name"] in ignore_list:
            continue
        folium_dict[item.name] = folium.TileLayer(
            tiles=item.build_url(),
            attr=item.attribution,
            name=item.name,
            max_zoom=item.get("max_zoom", 30),
            overlay=True,
            control=True,
        )

    if os.environ.get("PLANET_API_KEY") is not None:
        planet_dict = common.planet_tiles(tile_format="folium")
        folium_dict.update(planet_dict)

    return folium_dict

xyz_to_leaflet()

Convert xyz tile services to ipyleaflet tile layers.

Returns:

Type Description
dict[str, Any]

A dictionary of ipyleaflet tile layers.

Source code in geemap/basemaps.py
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
def xyz_to_leaflet() -> dict[str, Any]:
    """Convert xyz tile services to ipyleaflet tile layers.

    Returns:
        A dictionary of ipyleaflet tile layers.
    """
    leaflet_dict = {}
    # Ignore Esri basemaps if they are already in the custom XYZ_TILES.
    ignore_list = [XYZ_TILES[tile]["name"] for tile in XYZ_TILES]

    # Add custom tiles.
    for tile_type, tile_dict in custom_tiles.items():
        for tile_provider, tile_info in tile_dict.items():
            tile_info["type"] = tile_type
            tile_info["max_zoom"] = 30
            leaflet_dict[tile_info["name"]] = tile_info

    # Add xyzservices.provider tiles.
    for tile_provider, tile_info in get_xyz_dict().items():
        if tile_info["name"] in ignore_list:
            continue
        tile_info["url"] = tile_info.build_url()
        tile_info["max_zoom"] = 30
        leaflet_dict[tile_info["name"]] = tile_info

    return leaflet_dict

xyz_to_plotly()

Convert xyz tile services to plotly tile layers.

Returns:

Type Description
dict[str, Any]

A dictionary of plotly tile layers.

Source code in geemap/basemaps.py
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
def xyz_to_plotly() -> dict[str, Any]:
    """Convert xyz tile services to plotly tile layers.

    Returns:
        A dictionary of plotly tile layers.
    """
    plotly_dict = {}
    # Ignore Esri basemaps if they are already in the custom XYZ_TILES.
    ignore_list = [XYZ_TILES[tile]["name"] for tile in XYZ_TILES]

    for key, tile in custom_tiles["xyz"].items():
        plotly_dict[key] = {
            "below": "traces",
            "sourcetype": "raster",
            "sourceattribution": tile["attribution"],
            "source": [tile["url"]],
            "name": key,
        }

    for item in get_xyz_dict().values():
        if item["name"] in ignore_list:
            continue
        plotly_dict[item.name] = {
            "below": "traces",
            "sourcetype": "raster",
            "sourceattribution": item.attribution,
            "source": [item.build_url()],
            "name": item.name,
        }

    return plotly_dict

xyz_to_pydeck()

Convert xyz tile services to pydeck custom tile layers.

Returns:

Type Description
dict[str, Any]

A dictionary of pydeck tile layers.

Source code in geemap/basemaps.py
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
def xyz_to_pydeck() -> dict[str, Any]:
    """Convert xyz tile services to pydeck custom tile layers.

    Returns:
        A dictionary of pydeck tile layers.
    """
    import pydeck as pdk

    pydeck_dict = {}
    # Ignore Esri basemaps if they are already in the custom XYZ_TILES.
    ignore_list = [XYZ_TILES[tile]["name"] for tile in XYZ_TILES]

    for key, tile in custom_tiles["xyz"].items():
        url = tile["url"]
        pydeck_dict[key] = url

    for key, item in get_xyz_dict().items():
        if item["name"] in ignore_list:
            continue
        url = item.build_url()
        pydeck_dict[key] = url

        if os.environ.get("PLANET_API_KEY") is not None:
            planet_dict = common.planet_tiles(tile_format="ipyleaflet")
            for id_, tile in planet_dict.items():
                pydeck_dict[id_] = tile.url

    pdk.settings.custom_libraries = [
        {
            "libraryName": "MyTileLayerLibrary",
            "resourceUri": "https://cdn.jsdelivr.net/gh/giswqs/pydeck_myTileLayer@master/dist/bundle.js",
        }
    ]

    for key in pydeck_dict:
        pydeck_dict[key] = pdk.Layer("MyTileLayer", pydeck_dict[key], key)

    return pydeck_dict