Complete implementation of real terrain data (SRTM) integration for RF propagation simulation in the Heimdall SDR platform.
This implementation adds realistic terrain-based RF propagation modeling using SRTM (Shuttle Radar Topography Mission) elevation data from OpenTopography API.
services/training/src/data/terrain.py)SRTMDownloaderheimdall-terrainheimdall.terrain_tiles with status trackingservices/training/src/data/terrain.py)TerrainLookupservices/training/src/data/propagation.py)calculate_terrain_loss()sqrt(λ * d1 * d2 / D)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 |
services/backend/src/models/terrain.py)TerrainTile: Tile metadataTerrainTilesList: List responseDownloadRequest/Response: Download operationsCoverageStatus: Coverage analysisElevationQuery/Response: Elevation queriesfrontend/src/store/terrainStore.ts)fetchTiles(): Load all tilesfetchCoverage(): Get coverage statusdownloadWebSDRRegion(): Auto-download tiles for WebSDR areadeleteTile(name): Remove tilequeryElevation(lat, lon): Get elevationfrontend/src/services/api/terrain.ts)frontend/src/pages/TerrainManagement.tsx)Features:
frontend/src/pages/TrainingDashboard.tsx)use_real_terrain flag to backendTerrainLookup with MinIO client when enabledph-mountains/terrainAdd to .env:
OPENTOPOGRAPHY_API_KEY=your_key_here
Get free API key at: https://www.opentopography.org/
Added to both backend and training services:
environment:
OPENTOPOGRAPHY_API_KEY: ${OPENTOPOGRAPHY_API_KEY:-}
Added to services/requirements/data.txt:
rasterio>=1.3.9
aiohttp>=3.9.0
For NW Italy WebSDR network (6 stations):
Fresnel Zone: Ellipsoid around LOS ray where RF energy travels
r = sqrt(λ * d1 * d2 / D)
Earth Curvature Correction:
h = d1 * d2 / (2 * R_earth)Loss Model:
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
Via API:
curl -X POST http://localhost:8001/api/v1/terrain/download \
-H "Content-Type: application/json" \
-d '{}'
Via UI:
Via API:
curl http://localhost:8001/api/v1/terrain/coverage
Via UI:
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"
}
Via UI:
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)
# 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)
Error: "No API key configured"
Solution: Set OPENTOPOGRAPHY_API_KEY in .env and restart services
Error: "HTTP 429: Too Many Requests"
Solution: Wait 24h or upgrade to paid OpenTopography plan
Error: "GDAL not found"
Solution: Add to Dockerfile:
RUN apt-get update && apt-get install -y gdal-bin libgdal-dev
Error: "Tile N44E007 not found in MinIO"
Solution: Download tile via /api/v1/terrain/download endpoint
Warning: "Mapbox token not configured"
Solution: Set VITE_MAPBOX_TOKEN in .env (free at https://mapbox.com)
When modifying terrain system:
Part of Heimdall SDR project - CC Non-Commercial