Skip to content

113 titiler cmr

image image

Visualizing NASA Earthdata with TiTiler CMR

This notebook demonstrates how to visualize NASA Earthdata collections on interactive maps using leafmap and the TiTiler CMR endpoint.

TiTiler CMR provides dynamic tiling services for NASA's Common Metadata Repository (CMR) collections, allowing you to visualize large-scale Earth science datasets directly on web maps without downloading the data.

Key Features: - Access NASA Earthdata collections using concept IDs - Support for both rasterio (COGs) and xarray (NetCDF/Zarr) backends - Dynamic rescaling and colormap application - Time series visualization with interactive sliders - Band math expressions for derived products (e.g., NDVI)

References: - TiTiler CMR GitHub - NASA Earthdata CMR - NASA Earthdata Search

Installation

Uncomment the following line to install leafmap if needed.

1
# %pip install -U leafmap
1
import leafmap

Understanding NASA CMR Concept IDs

Each NASA Earthdata collection has a unique Concept ID. You can find concept IDs by:

  1. Searching on NASA Earthdata Search
  2. Using the CMR API

Common concept IDs used in this notebook:

Dataset Concept ID Backend Description
MUR SST C2036881735-POCLOUD xarray Sea Surface Temperature
HLS Landsat C2021957657-LPCLOUD rasterio Harmonized Landsat Sentinel-2
HLS Sentinel-2 C2021957295-LPCLOUD rasterio Harmonized Landsat Sentinel-2

Example 1: Sea Surface Temperature (xarray backend)

The MUR Sea Surface Temperature dataset uses the xarray backend because it's stored as NetCDF/Zarr format. We need to specify the variable parameter for xarray datasets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
m = leafmap.Map(center=[0, 0], zoom=2)
m.add_cmr_layer(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
    rescale="270,305",
    colormap_name="thermal",
    name="Sea Surface Temperature",
)
m

Example 2: HLS Landsat True Color (rasterio backend)

The Harmonized Landsat Sentinel-2 (HLS) dataset uses the rasterio backend because it's stored as Cloud Optimized GeoTIFFs (COGs). We can specify bands for RGB visualization.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
m = leafmap.Map(center=[46.7653, -91.0321], zoom=10)
m.add_cmr_layer(
    concept_id="C2021957657-LPCLOUD",
    datetime="2024-08-06T00:00:00Z/2024-08-06T23:59:59Z",
    backend="rasterio",
    bands=["B04", "B03", "B02"],
    bands_regex="B[0-9][0-9]",
    color_formula="Gamma RGB 3.5 Saturation 1.7 Sigmoidal RGB 15 0.35",
    name="HLS Landsat True Color",
    titiler_cmr_endpoint="https://staging.openveda.cloud/api/titiler-cmr",
)
m

Example 3: NDVI with Band Math Expression

You can use band math expressions to create derived products like NDVI (Normalized Difference Vegetation Index).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
m = leafmap.Map(center=[46.7653, -91.0321], zoom=10)
m.add_cmr_layer(
    concept_id="C2021957657-LPCLOUD",
    datetime="2024-08-06T00:00:00Z/2024-08-06T23:59:59Z",
    backend="rasterio",
    expression="(B05-B04)/(B05+B04)",
    bands_regex="B[0-9][0-9]",
    rescale="-1,1",
    colormap_name="rdylgn",
    name="NDVI",
)
m
1
m.layers

Example 4: Sea Ice Fraction Time Series

The add_cmr_timeseries method creates an interactive time slider for temporal datasets. This is useful for visualizing changes over time.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
m = leafmap.Map(center=[70, -45], zoom=3)  # Arctic region
m.add_cmr_timeseries(
    concept_id="C2036881735-POCLOUD",
    datetime="2023-11-01T00:00:00Z/2024-03-01T00:00:00Z",
    step="P1M",  # Monthly time steps
    backend="xarray",
    variable="sea_ice_fraction",
    colormap_name="blues_r",
    rescale="0,1",
    name_prefix="Sea Ice",
)
m

Using the Low-Level API Functions

Leafmap also provides low-level functions for more control over the CMR tile requests.

Get TileJSON Metadata

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from leafmap.stac import cmr_tilejson, cmr_bounds, cmr_center

# Get TileJSON metadata
tilejson = cmr_tilejson(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
    colormap_name="thermal",
    rescale="270,305",
)

if tilejson:
    print(f"Tile URL: {tilejson.get('tiles', ['N/A'])[0][:80]}...")
    print(f"Bounds: {tilejson.get('bounds')}")
    print(f"Center: {tilejson.get('center')}")
    print(f"Min Zoom: {tilejson.get('minzoom')}")
    print(f"Max Zoom: {tilejson.get('maxzoom')}")

Get Bounds and Center

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Get bounds
bounds = cmr_bounds(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
)
print(f"Bounds: {bounds}")

# Get center
center = cmr_center(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
)
print(f"Center (lon, lat): {center}")

Using with Folium Backend

The add_cmr_layer method is also available in the Folium backend.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import leafmap.foliumap as leafmap_folium

m = leafmap_folium.Map(center=[0, 0], zoom=2)
m.add_cmr_layer(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
    rescale="270,305",
    colormap_name="thermal",
    name="Sea Surface Temperature",
)
m

Using with MapLibre Backend

The add_cmr_layer method is also available in the MapLibre backend.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import leafmap.maplibregl as leafmap_maplibre

m = leafmap_maplibre.Map(center=[0, 0], zoom=1)
m.add_cmr_layer(
    concept_id="C2036881735-POCLOUD",
    datetime="2024-01-15T00:00:00Z",
    backend="xarray",
    variable="analysed_sst",
    rescale="270,305",
    colormap_name="thermal",
    name="Sea Surface Temperature",
)
m

Common NASA Earthdata Collections

Here are some commonly used NASA Earthdata collections:

Sea Surface Temperature (MUR SST)

  • Concept ID: C2036881735-POCLOUD
  • Backend: xarray
  • Variables: analysed_sst, analysis_error, mask, sea_ice_fraction
  • Rescale: 270,305 (Kelvin)

Harmonized Landsat Sentinel-2 (HLS)

  • Landsat Concept ID: C2021957657-LPCLOUD
  • Sentinel-2 Concept ID: C2021957295-LPCLOUD
  • Backend: rasterio
  • Bands: B01-B12, Fmask
  • Common band combinations:
  • True Color: B04, B03, B02
  • False Color: B05, B04, B03
  • NDVI: (B05-B04)/(B05+B04)

ISO 8601 Duration Codes for Time Steps

  • P1D: 1 day
  • P1W: 1 week
  • P2W: 2 weeks
  • P1M: 1 month
  • P1Y: 1 year

Summary

Key functions for visualizing NASA Earthdata with TiTiler CMR:

Map Methods: - map.add_cmr_layer() - Add a single CMR layer to the map - map.add_cmr_timeseries() - Add a time series with interactive slider (ipyleaflet only)

Low-Level Functions: - leafmap.stac.cmr_tilejson() - Get TileJSON metadata - leafmap.stac.cmr_tile() - Get tile URL template - leafmap.stac.cmr_bounds() - Get geographic bounds - leafmap.stac.cmr_center() - Get center coordinates - leafmap.stac.cmr_timeseries_tilejson() - Get time series TileJSON - leafmap.stac.cmr_animated_gif() - Generate animated GIF - leafmap.stac.cmr_statistics() - Calculate statistics for an AOI

Key Parameters: - concept_id - NASA CMR collection ID - datetime - Date or date range (RFC3339 format) - backend - 'rasterio' for COGs, 'xarray' for NetCDF/Zarr - variable - Variable name (required for xarray backend) - bands - Band names for rasterio backend - expression - Band math expression - rescale - Min/max values for rescaling - colormap_name - Colormap name (e.g., 'thermal', 'viridis')