Skip to content

basemaps module

Module for basemaps.

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

For example, to access Google basemaps, users first need to get a Google Maps API key from https://bit.ly/3sw0THG. Then, set the environment variable using geemap.set_api_key(). Then Google basemaps can be accessed using:

1
2
3
4
* `basemaps['ROADMAP']`
* `basemaps['SATELLITE']`
* `basemaps['TERRAIN']`
* `basemaps['HYBRID']`

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

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

A dictionary of xyz services.

Source code in leafmap/basemaps.py
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
def get_xyz_dict(free_only=True, france=False):
    """Returns a dictionary of xyz services.

    Args:
        free_only (bool, optional): Whether to return only free xyz tile
            services that do not require an access token. Defaults to True.
        france (bool, optional): 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

ipyleaflet.TileLayer: An ipyleaflet tile layer.

Source code in leafmap/basemaps.py
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
def qms_to_geemap(service_id):
    """Convert a qms service to an ipyleaflet tile layer.

    Args:
        service_id (str): Service ID.

    Returns:
        ipyleaflet.TileLayer: 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, timeout=600)

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 leafmap/basemaps.py
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
def search_qms(keywords, limit=10, timeout=600):
    """Search qms files for keywords. Reference: https://github.com/geopandas/xyzservices/issues/65

    Args:
        keywords (str): Keywords to search for.
        limit (int): 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)}",
        timeout=timeout,
    )
    services = services.json()
    if services["count"] == 0:
        return None
    elif services["count"] <= limit:
        return services["results"]
    else:
        return services["results"][:limit]

xyz_to_bokeh()

Convert xyz tile services to bokeh tile layers.

Returns:

Name Type Description
dict

A dictionary of bokeh tile layers.

Source code in leafmap/basemaps.py
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
def xyz_to_bokeh():
    """Convert xyz tile services to bokeh tile layers.

    Returns:
        dict: A dictionary of bokeh tile layers.
    """
    from bokeh.models import WMTSTileSource

    bokeh_dict: Dict[str, WMTSTileSource] = {}

    for key, tile_info in XYZ_TILES.items():
        if "url" not in tile_info or "attribution" not in tile_info:
            raise ValueError(
                f"Invalid tile configuration for key {key}. Missing 'url' or attribution."
            )

        url: str = tile_info["url"]
        attribution: str = tile_info["attribution"]

        tile_options: Dict[str, Any] = {
            "url": url,
            "attribution": attribution,
        }

        bokeh_dict[key] = WMTSTileSource(**tile_options)

    return bokeh_dict

xyz_to_folium()

Convert xyz tile services to folium tile layers.

Returns:

Name Type Description
dict

A dictionary of folium tile layers.

Source code in leafmap/basemaps.py
336
337
338
339
340
341
342
343
344
345
346
347
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
381
382
383
384
def xyz_to_folium():
    """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=22,
        )

    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,
        )

    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", 22),
            overlay=True,
            control=True,
        )

    if os.environ.get("PLANET_API_KEY") is not None:
        planet_dict = 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:

Name Type Description
dict

A dictionary of ipyleaflet tile layers.

Source code in leafmap/basemaps.py
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
def xyz_to_leaflet():
    """Convert xyz tile services to ipyleaflet tile layers.

    Returns:
        dict: 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_info in tile_dict.items():
            tile_info["type"] = tile_type
            leaflet_dict[tile_info["name"]] = tile_info

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

    return leaflet_dict

xyz_to_plotly()

Convert xyz tile services to plotly tile layers.

Returns:

Name Type Description
dict

A dictionary of plotly tile layers.

Source code in leafmap/basemaps.py
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
def xyz_to_plotly():
    """Convert xyz tile services to plotly tile layers.

    Returns:
        dict: 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:

Name Type Description
dict

A dictionary of pydeck tile layers.

Source code in leafmap/basemaps.py
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
415
416
417
418
419
420
421
422
423
424
425
426
def xyz_to_pydeck():
    """Convert xyz tile services to pydeck custom tile layers.

    Returns:
        dict: A dictionary of pydeck tile layers.
    """

    check_package("pydeck", "https://deckgl.readthedocs.io/en/latest/installation.html")
    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 = 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