添加docker部署代码
This commit is contained in:
35
.dockerignore
Normal file
35
.dockerignore
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.claude
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
.venv
|
||||||
|
venv/
|
||||||
|
.env
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
CLAUDE.md
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# UV
|
||||||
|
.python-version
|
||||||
|
uv.lock
|
||||||
126
CLAUDE.md
Normal file
126
CLAUDE.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# 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
|
||||||
|
```
|
||||||
26
Dockerfile
Normal file
26
Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
libssl-dev \
|
||||||
|
libffi-dev \
|
||||||
|
curl \
|
||||||
|
libexpat1 \
|
||||||
|
gdal-bin \
|
||||||
|
libgdal-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
||||||
|
|
||||||
|
COPY pyproject.toml ./
|
||||||
|
COPY app_mars.py ./
|
||||||
|
|
||||||
|
RUN uv pip install --system -e .
|
||||||
|
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
EXPOSE 8002
|
||||||
|
|
||||||
|
CMD ["uv", "run", "uvicorn", "app_mars:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
@@ -1,2 +1,9 @@
|
|||||||
# rio-tiler-tms
|
# rio-tiler-tms
|
||||||
|
|
||||||
|
## 手动构建镜像
|
||||||
|
|
||||||
|
sudo docker build -t rio-tiler-mars:latest .
|
||||||
|
|
||||||
|
## 启动服务
|
||||||
|
|
||||||
|
sudo docker compose up -d
|
||||||
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
services:
|
||||||
|
mars:
|
||||||
|
image: rio-tiler-mars:latest
|
||||||
|
container_name: rio-tiler-mars
|
||||||
|
ports:
|
||||||
|
- "8002:8000"
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8002/tilejson.json"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
Reference in New Issue
Block a user