heimdall

SRTM Terrain System Implementation

Complete implementation of real terrain data (SRTM) integration for RF propagation simulation in the Heimdall SDR platform.

🎯 Overview

This implementation adds realistic terrain-based RF propagation modeling using SRTM (Shuttle Radar Topography Mission) elevation data from OpenTopography API.

Key Features

📦 Components Implemented

Backend (Python/FastAPI)

1. SRTM Downloader (services/training/src/data/terrain.py)

2. Terrain Lookup (services/training/src/data/terrain.py)

3. RF Propagation (services/training/src/data/propagation.py)

4. API Endpoints (services/backend/src/routers/terrain.py)

Endpoint Method Description
/api/v1/terrain/tiles GET List all tiles with status
/api/v1/terrain/download POST Download tiles (auto-detect or custom bounds)
/api/v1/terrain/coverage GET Coverage status for WebSDR region
/api/v1/terrain/elevation GET Query elevation at lat/lon
/api/v1/terrain/tiles/{name} DELETE Delete tile from DB and MinIO

5. Pydantic Models (services/backend/src/models/terrain.py)

Frontend (React/TypeScript)

1. Terrain Store (frontend/src/store/terrainStore.ts)

2. API Client (frontend/src/services/api/terrain.ts)

3. Terrain Management Page (frontend/src/pages/TerrainManagement.tsx)

Features:

4. Training Integration (frontend/src/pages/TrainingDashboard.tsx)

5. Navigation

🛠️ Configuration

Environment Variables

Add to .env:

OPENTOPOGRAPHY_API_KEY=your_key_here

Get free API key at: https://www.opentopography.org/

Docker Compose

Added to both backend and training services:

environment:
  OPENTOPOGRAPHY_API_KEY: ${OPENTOPOGRAPHY_API_KEY:-}

Dependencies

Added to services/requirements/data.txt:

rasterio>=1.3.9
aiohttp>=3.9.0

🗺️ Coverage Area

For NW Italy WebSDR network (6 stations):

📊 Technical Details

SRTM Data

RF Propagation Physics

Fresnel Zone: Ellipsoid around LOS ray where RF energy travels

Earth Curvature Correction:

Loss Model:

Database Schema

Table heimdall.terrain_tiles (already exists):

- tile_name VARCHAR(50) UNIQUE -- e.g., 'N44E007'
- lat_min, lat_max, lon_min, lon_max INTEGER
- minio_bucket VARCHAR(100)
- minio_path VARCHAR(255)
- file_size_bytes BIGINT
- status VARCHAR(20) -- pending/downloading/ready/failed
- error_message TEXT
- checksum_sha256 VARCHAR(64)
- source_url TEXT
- downloaded_at, created_at, updated_at TIMESTAMP

🚀 Usage

1. Download Tiles

Via API:

curl -X POST http://localhost:8001/api/v1/terrain/download \
  -H "Content-Type: application/json" \
  -d '{}'

Via UI:

  1. Navigate to “Terrain Management”
  2. Click “Download WebSDR Region”
  3. Wait for download completion (~2-5 minutes)

2. Check Coverage

Via API:

curl http://localhost:8001/api/v1/terrain/coverage

Via UI:

3. Query Elevation

Via API:

curl "http://localhost:8001/api/v1/terrain/elevation?lat=45.0&lon=8.0"

Response:

{
  "lat": 45.0,
  "lon": 8.0,
  "elevation_m": 327.5,
  "tile_name": "N45E008",
  "source": "srtm"
}

4. Generate Training Data with SRTM

Via UI:

  1. Go to “Training Dashboard”
  2. Click “Generate Synthetic Data”
  3. Check “Use Real Terrain Data (SRTM)”
  4. Configure parameters
  5. Click “Generate”

Via API:

data = {
    "name": "dataset_with_terrain",
    "num_samples": 10000,
    "use_real_terrain": True,
    # ... other parameters
}
response = requests.post("/api/v1/training/synthetic", json=data)

🔍 Verification Tests

Backend Tests

# 1. Download tiles
curl -X POST http://localhost:8001/api/v1/terrain/download

# Expected: {"successful": 6, "failed": 0, "total": 6}

# 2. List tiles
curl http://localhost:8001/api/v1/terrain/tiles

# Expected: 6 tiles with status="ready"

# 3. Query elevation
curl "http://localhost:8001/api/v1/terrain/elevation?lat=45.0&lon=8.0"

# Expected: elevation_m between 200-500m, source="srtm"

# 4. Check database
psql -U heimdall_user -d heimdall -c \
  "SELECT tile_name, status, file_size_bytes FROM heimdall.terrain_tiles;"

# Expected: 6 rows with status='ready'

# 5. Check MinIO
docker exec heimdall-minio mc ls minio/heimdall-terrain/tiles/

# Expected: 6 .tif files (~50-100MB each)

Frontend Tests

  1. Navigate to http://localhost:5173/terrain
  2. Verify:
    • Map displays with satellite imagery
    • 6 green tile boundaries visible
    • Coverage status shows 100%
    • Table lists 6 tiles with “ready” status
    • File sizes show ~50-100 MB per tile

Integration Test

  1. Go to Training Dashboard
  2. Create synthetic dataset with SRTM enabled
  3. Check logs for: “Using SRTM terrain data”
  4. Verify improved realism in propagation loss values

📈 Performance

🐛 Troubleshooting

API Key Issues

Error: "No API key configured"

Solution: Set OPENTOPOGRAPHY_API_KEY in .env and restart services

Rate Limit

Error: "HTTP 429: Too Many Requests"

Solution: Wait 24h or upgrade to paid OpenTopography plan

rasterio Install Failure

Error: "GDAL not found"

Solution: Add to Dockerfile:

RUN apt-get update && apt-get install -y gdal-bin libgdal-dev

Tile Not Found

Error: "Tile N44E007 not found in MinIO"

Solution: Download tile via /api/v1/terrain/download endpoint

Mapbox Token Missing

Warning: "Mapbox token not configured"

Solution: Set VITE_MAPBOX_TOKEN in .env (free at https://mapbox.com)

🔮 Future Enhancements

📚 References

🤝 Contributing

When modifying terrain system:

  1. Update this document
  2. Add tests for new features
  3. Verify backward compatibility
  4. Update API documentation
  5. Test with real WebSDR data

📄 License

Part of Heimdall SDR project - CC Non-Commercial