|
| 1 | +# titiler-cmr Showcase |
| 2 | + |
| 3 | +A minimal map application showcasing [titiler-cmr](https://developmentseed.org/titiler-cmr)'s data rendering capability, hosted on GitHub Pages. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- Globe projection by default (MapLibre GL JS v5) |
| 8 | +- Tile loading indicator (tile fetches from titiler-cmr can be slow) |
| 9 | +- Per-layer minimum zoom enforcement with a visual prompt to zoom in |
| 10 | +- Dataset / collection / render switching with live tile updates |
| 11 | +- Date and date-range pickers |
| 12 | +- Advanced query parameter controls (cloud cover, orbit direction, etc.) |
| 13 | +- Mobile-friendly collapsible controls panel |
| 14 | + |
| 15 | +## Datasets |
| 16 | + |
| 17 | +| Dataset | Collections | Backend | |
| 18 | +|---|---|---| |
| 19 | +| HLS (Harmonized Landsat Sentinel-2) | HLSL30 (Landsat 8/9), HLSS30 (Sentinel-2) | rasterio | |
| 20 | +| NISAR Beta GCOV | NISAR L2 GCOV | xarray | |
| 21 | +| MUR Sea Surface Temperature | MUR SST | xarray | |
| 22 | + |
| 23 | +## Development |
| 24 | + |
| 25 | +```bash |
| 26 | +npm install |
| 27 | +npm run dev # start dev server |
| 28 | +npm run build # TypeScript check + Vite production build |
| 29 | +npm run preview # preview production build locally |
| 30 | +npm run deploy # build and push dist/ to gh-pages branch |
| 31 | +``` |
| 32 | + |
| 33 | +## Architecture |
| 34 | + |
| 35 | +Single-page static site — no server-side code. |
| 36 | + |
| 37 | +``` |
| 38 | +src/ |
| 39 | + config.ts # TITILER_ENDPOINT, type definitions, DATASETS array |
| 40 | + main.ts # Map init; wires controls → layers → zoom-guard → loading |
| 41 | + controls.ts # Dataset/collection/render selects, date picker, extra params |
| 42 | + layers.ts # updateLayer(): removes old source/layer, builds TileJSON URL, adds raster source |
| 43 | + loading.ts # Shows spinner on map dataloading, hides on idle |
| 44 | + zoom-guard.ts # Shows message when zoom < collection.minzoom |
| 45 | + style.css # Full-viewport map, absolute-positioned overlay panels |
| 46 | +``` |
| 47 | + |
| 48 | +The titiler-cmr endpoint is configured in `src/config.ts` as `TITILER_ENDPOINT`. Swap this value to point at a different environment. |
| 49 | + |
| 50 | +## Adding a Dataset |
| 51 | + |
| 52 | +Add a new `DatasetConfig` entry to the `DATASETS` array in `src/config.ts`. No other code changes are needed. |
| 53 | + |
| 54 | +Each `CollectionConfig` requires: |
| 55 | + |
| 56 | +| Field | Description | |
| 57 | +|---|---| |
| 58 | +| `collectionConceptId` | NASA CMR collection concept ID | |
| 59 | +| `backend` | `rasterio` (GeoTIFF/COG) or `xarray` (NetCDF/HDF5) | |
| 60 | +| `minzoom` / `maxzoom` | Zoom range for tile requests | |
| 61 | +| `date` | `{ mode: "single", default: "YYYY-MM-DD" }` or `{ mode: "range", default: ["YYYY-MM-DD", "YYYY-MM-DD"] }` | |
| 62 | +| `renders` | Array of `RenderConfig` objects (label, assets/variables, query params) | |
| 63 | +| `queryParams` | Optional extra controls: `range`, `select`, `text`, or `attribute` | |
| 64 | + |
| 65 | +A dataset with a single collection hides the collection selector in the UI. A dataset with multiple collections shows it. |
| 66 | + |
| 67 | +## Layer Update Flow |
| 68 | + |
| 69 | +1. Any control change calls `updateLayer(map, state)`. |
| 70 | +2. All previous CMR sources/layers (`cmr-0` … `cmr-7`) are removed. |
| 71 | +3. A TileJSON URL is built from the current state and added as a MapLibre `raster` source. MapLibre fetches the TileJSON natively and renders the tiles. |
| 72 | +4. Renders that define `subLayers` produce one map layer per sub-layer (used by NISAR to switch between frequency-A and frequency-B grids based on zoom level). |
0 commit comments