This repository has been archived on 2026-03-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
rio-tiler-tms/CLAUDE.md

127 lines
3.9 KiB
Markdown
Raw Permalink Normal View History

2026-02-25 09:28:37 +08:00
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a collection of FastAPI-based tile servers that use rio-tiler to serve COG (Cloud Optimized GeoTIFF) files as dynamic map tiles. The project serves imagery from different planetary bodies:
- **app.py** - NJ 2020 aerial imagery (I7D16.tif) - UInt16 data with per-band rescaling
- **app_world.py** - Natural Earth global basemap (HYP_HR_SR_OB_DR_cog.tif) - uint8 RGB
- **app_mars.py** - Mars MGS MOLA global basemap - Uses custom Mars CRS in equidistant cylindrical projection
## Running the Servers
Each app is an independent FastAPI application. Run with uvicorn:
```bash
# Run NJ imagery server (default port 8000)
uvicorn app:app --reload
# Run world basemap server
uvicorn app_world:app --port 8001 --reload
# Run Mars basemap server
uvicorn app_mars:app --port 8002 --reload
```
## Architecture
### Common Pattern (app.py, app_world.py)
All apps follow the same pattern using `rio_tiler.io.Reader`:
1. **Tile endpoint** (`/tiles/{z}/{x}/{y}.png`) - Reads COG tiles and returns PNG
2. **TileJSON endpoint** (`/tilejson.json`) - Returns TileJSON 2.2.0 metadata
3. **Optional viewer** (`/`) - app.py includes a Leaflet.js viewer
Key rio-tiler concepts:
- `Reader(DATA_PATH)` context manager for reading COGs
- `cog.tile(x, y, z)` to extract tiles
- `img.render()` with `img_profiles` for output formatting
- `cog.get_geographic_bounds()` for bounds in geographic CRS
- `cog.minzoom`/`cog.maxzoom` for zoom levels
### Mars CRS (app_mars.py)
The Mars server uses a **custom TileMatrixSet** to handle Mars-specific coordinate system:
- **CRS**: Simple Cylindrical Mars (equidistant cylindrical, meters)
- **Sphere radius**: 3,396,190 m (vs Earth's ~6,378,137 m)
- **Extent**: ±πR in x, ±πR/2 in y (calculated from Mars radius)
- **matrix_scale=[2, 1]**: 2×1 tiles at zoom 0, matching Cesium's GeographicTilingScheme
**Critical design decision**: TMS and TIF both use the same Mars CRS (eqc meters). Avoid using longlat (degrees) because PROJ would attempt datum transformation through WGS84, causing "PROJ: eqc: Invalid latitude" errors due to the large sphere radius difference.
```python
MARS_CRS = CRS.from_proj4(
"+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +a=3396190 +b=3396190 +units=m +no_defs"
)
MARS_TMS = TileMatrixSet.custom(
crs=MARS_CRS,
extent=(-_MAX_X, -_MAX_Y, _MAX_X, _MAX_Y),
matrix_scale=[2, 1],
)
```
Pass custom TMS to Reader: `Reader(DATA_PATH, tms=MARS_TMS)`
## Data Handling
### Rescaling (app.py)
For UInt16 imagery, use per-band rescaling based on p2/p98 statistics:
```python
RESCALE = [
(6130, 40453), # Red
(10641, 41211), # Green
(12482, 36323), # Blue
]
img.render(img_format="PNG", rescale=RESCALE, **img_profiles.get("png", {}))
```
### uint8 Data (app_world.py, app_mars.py)
No rescaling needed for pre-scaled uint8 imagery:
```python
img.render(img_format="PNG", **img_profiles.get("png", {}))
```
## Dependencies
Managed via uv with `pyproject.toml`:
- fastapi - Web framework
- rio-tiler - COG tiling engine
- rasterio - GeoTIFF I/O
- uvicorn - ASGI server
- pyproj, morecantile - CRS and TMS handling (for Mars app)
## Adding New Tile Servers
To add a new COG tile server:
1. Copy the appropriate template (app.py for UInt16, app_world.py/app_mars.py for uint8)
2. Update `DATA_PATH` to point to your COG file in `data/`
3. For non-Earth data, create a custom CRS/TMS following app_mars.py pattern
4. Adjust rescaling if needed for UInt16 data
5. Update app metadata (title, description)
6. Run with uvicorn on a unique port
## File Structure
```
data/ # COG files (gitignored)
├── I7D16.tif
├── HYP_HR_SR_OB_DR_cog.tif
└── Mars_MGS_MOLA_...tif
app.py # NJ imagery server
app_world.py # World basemap server
app_mars.py # Mars basemap server
pyproject.toml # uv dependencies
```