113 titiler cmr
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:
Installation¶
Uncomment the following line to install leafmap if needed.
# %pip install -U leafmap
import leafmap
Understanding NASA CMR Concept IDs¶
Each NASA Earthdata collection has a unique Concept ID. You can find concept IDs by:
- Searching on NASA Earthdata Search
- 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.
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.
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).
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
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.
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¶
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¶
# 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.
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.
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 mapmap.add_cmr_timeseries()- Add a time series with interactive slider (ipyleaflet only)
Low-Level Functions:
leafmap.stac.cmr_tilejson()- Get TileJSON metadataleafmap.stac.cmr_tile()- Get tile URL templateleafmap.stac.cmr_bounds()- Get geographic boundsleafmap.stac.cmr_center()- Get center coordinatesleafmap.stac.cmr_timeseries_tilejson()- Get time series TileJSONleafmap.stac.cmr_animated_gif()- Generate animated GIFleafmap.stac.cmr_statistics()- Calculate statistics for an AOI
Key Parameters:
concept_id- NASA CMR collection IDdatetime- Date or date range (RFC3339 format)backend- 'rasterio' for COGs, 'xarray' for NetCDF/Zarrvariable- Variable name (required for xarray backend)bands- Band names for rasterio backendexpression- Band math expressionrescale- Min/max values for rescalingcolormap_name- Colormap name (e.g., 'thermal', 'viridis')